/* ============================================================================
   The Catalog — theme layer (day / night) and direction layer (LTR / RTL).

   Two rules keep this file small and honest:

   1. The dark ramp in `hub.css` is the *authored* one — this catalogue was drawn
      dark and every variation inherits that. So light mode is expressed as an
      inversion of the ramp rather than as a second stylesheet: index 000 is the
      page, 700 is the body text, and flipping those two ends of the scale flips
      the whole shell consistently because every component already agreed on it.
   2. Direction is a property of the document, not a second layout. Anything that
      must mirror uses logical properties (`inset-inline-start`, `margin-inline`,
      `text-align: start`); the handful of genuinely directional flourishes are
      handled with `[dir="rtl"]` overrides further down, and each one is annotated.
   ========================================================================= */

/* ------------------------------------------------------------------ day ---- */

/* The one place the theme is *asserted*, not inherited: every translucent ink in the shell —
   text, hairlines, hover washes, the lightening pass on accent chips — is written as
   `rgb(var(--fg-rgb) / α)` instead of `rgba(255,255,255,α)`. On the dark ramp the triplet is
   white and nothing changes; on paper it is near-black, so a decade of white-on-dark styling
   inverts in one declaration rather than in 39 patches that go stale one at a time. */
:root,
[data-theme="dark"] {
  --fg-rgb: 255 255 255;
  --bg-rgb: 5 5 6;
  --accent-weight: 100%;
  --fill-mix: 100%;
  --muted-alpha: 0.66;
  --label-alpha: 0.5;
  --ghost-alpha: 16%;
}

[data-theme="light"] {
  --fg-rgb: 24 21 15;
  --bg-rgb: 247 244 236;
  /* Accents are shared with the manifest, so they cannot simply be swapped per theme: instead
     every rule that uses an accent *as text* mixes it with the ink at this weight. On the night
     ramp the mix is a no-op (100% accent); on paper the accent is pulled towards the body colour
     until it passes contrast — a neon that stays legible instead of a pastel that does not. */
  --accent-weight: 42%; /* measured: 62% left accent text at 3.3:1 on paper, 48% at 3.9:1 */
  /* Accent *fills* (badges, pills, the active chip) keep their hue but deepen on paper, so the
     page-coloured text that sits on them stays readable instead of becoming a pastel smudge. */
  --fill-mix: 38%; /* measured: 44% left chartreuse and mint fills at 4.1–4.5:1 on paper */
  --label-alpha: 0.62; /* small uppercase labels: 0.34 is invisible on paper */
  --ghost-alpha: 26%;
  --muted-alpha: 0.66; /* muted copy must clear 4.5:1 in *both* ramps, not just on paper */
  --ink-000: #f7f4ec; /* page */
  --ink-050: #f2eee3;
  --ink-100: #ffffff; /* raised surfaces, cards, the stage frame */
  --ink-200: #fbf9f4;
  --ink-300: #e6e1d3; /* hairlines and rails */
  --ink-400: #c7c1b0; /* disabled strokes */
  --ink-500: #5f5a4b; /* muted labels — darkened from #8b8574: at 3.2:1 it failed on paper */
  --ink-600: #56503f; /* secondary text */
  --ink-700: #191712; /* body text */
  --paper: #14130f; /* the "paper" accent inverts with the ramp */

  /* Accents keep their hue and lose their glow: on paper they read as ink. */
  --accent: #d81f9f;
  --accent-2: #2f5cf0;
  --accent-3: #04735a;
  --accent-4: #d02a10;
  --accent-5: #8a6a24;

  /* Chartreuse is unreadable as text on paper, so it becomes a deep olive and the
     pale wash it used to provide is carried by the paper tone itself. */
  --glow-alpha: 0.1;
  --aurora-alpha: 0.28;

  color-scheme: light;
}

/* The animated aurora is the hub's atmosphere; on paper it must not turn to sludge. */
[data-theme="light"] .aurora__blob {
  opacity: var(--aurora-alpha);
  filter: blur(70px) saturate(150%);
}

[data-theme="light"] .aurora__grain {
  opacity: 0.25;
  mix-blend-mode: multiply;
}

/* Cards in daylight: a real edge and a soft shadow instead of a glow. */
[data-theme="light"] .card,
[data-theme="light"] .panel,
[data-theme="light"] .stage__frame {
  box-shadow: 0 1px 0 rgba(20, 19, 15, 0.06), 0 18px 40px -28px rgba(20, 19, 15, 0.35);
}

/* ----------------------------------------------------------------- rtl ----- */

/* The masthead's stat block is the one place where a raw right margin is used to
   push a group to the trailing edge; make it logical so it mirrors. */
[dir="rtl"] .masthead__meta {
  margin-inline-start: 0;
}

/* Numbers keep their Western shape but read right-to-left inside Persian copy:
   `plaintext` lets the bidi algorithm place them without reordering the string. */
[dir="rtl"] .counter,
[dir="rtl"] .card__id,
[dir="rtl"] .hud__id,
[dir="rtl"] code,
[dir="rtl"] .hud__chip {
  unicode-bidi: plaintext;
}

/* The language switch is a two-part control; in RTL the active half moves. */
[dir="rtl"] .chrome__link--ext::after {
  content: "↖";
}

/* Latin-only furniture reads badly when mirrored, so it opts out explicitly. */
[dir="rtl"] .force-ltr {
  direction: ltr;
  unicode-bidi: isolate;
}

/* …and because it is Latin-only furniture, it is usually an identifier or a file path: minted to
   be unbreakable and therefore wider than a phone. Wrapping inside the token is the only honest
   option — a single line that runs off the edge is worse than a path split across two. */
.force-ltr {
  overflow-wrap: anywhere;
}

/* Persian needs more leading and a touch less tracking than the Latin ramp, and the
   display face is shorter — so the headline scale is nudged, not reinterpreted. */
[lang="fa"] body,
[dir="rtl"] body {
  line-height: var(--leading-body, 1.75);
}

[lang="fa"] .masthead__title,
[dir="rtl"] .masthead__title {
  letter-spacing: -0.01em;
  line-height: 1.12;
}

[lang="fa"] .kicker,
[dir="rtl"] .kicker {
  letter-spacing: 0.12em;
}

/* --------------------------------------------------------- theme switch ---- */

.theme-switch {
  display: inline-flex;
  align-items: center;
  gap: 0.15rem;
  padding: 0.15rem;
  border: 1px solid var(--ink-300);
  border-radius: 999px;
  background: var(--ink-050);
}

.theme-switch__button {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.35rem 0.6rem;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--ink-600);
  font: inherit;
  font-size: 0.74rem;
  letter-spacing: 0.06em;
  cursor: pointer;
}

.theme-switch__button[aria-pressed="true"] {
  background: var(--ink-700);
  color: var(--ink-000);
}

.theme-switch__glyph {
  font-size: 0.9em;
  line-height: 1;
}

/* ------------------------------------------------- light-mode masthead ---- */

/* The masthead is the one block drawn as a dark poster: a white-to-grey gradient headline, a
   glow behind it, and light-on-dark counters. In daylight those become invisible, so the
   headline takes an ink gradient and the glow becomes a tinted wash. */
[data-theme="light"] .masthead__title .line {
  background: linear-gradient(100deg, #1a1815 8%, #3b3630 55%, #6d6455 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

[data-theme="light"] .masthead__title .line--accent {
  background: linear-gradient(100deg, var(--accent-2), var(--accent-3));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* Both the kicker and the lede are authored as translucent white — the two elements on the page
   that a light theme cannot rescue with the ink ramp, because their colour is literal. */
[data-theme="light"] .masthead__lede {
  color: var(--ink-600);
}

[data-theme="light"] .kicker {
  color: var(--accent-2);
}

[data-theme="light"] .masthead__meta,
[data-theme="light"] .masthead__facts li {
  color: var(--ink-600);
}

[data-theme="light"] .masthead__facts b {
  color: var(--ink-700);
}

[data-theme="light"] .brand__name,
[data-theme="light"] .masthead__cta {
  color: var(--ink-700);
}

/* The dark masthead draws a hairline of white; on paper that is a stray bright line. */
[data-theme="light"] .masthead {
  border-bottom-color: var(--ink-300);
}

/* Colour transitions on a theme flip are a courtesy, not a light show. */
@media (prefers-reduced-motion: no-preference) {
  html.theme-transition,
  html.theme-transition body,
  html.theme-transition .card,
  html.theme-transition .panel,
  html.theme-transition .masthead {
    transition: background-color 320ms var(--ease-editorial), color 320ms var(--ease-editorial),
      border-color 320ms var(--ease-editorial);
  }
}

/* The view-transition API gives the flip a cross-fade for free where supported. */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 320ms;
}
