/* ==========================================================================
   Tech4TIME — theme.css
   Every colour token in the system, for both modes. Pure monochrome plus the
   metallic silver gradient derived from the logo — no hue is introduced.

   How the mode is chosen
     1. assets/js/theme-init.js runs synchronously in <head> and stamps
        data-theme="light" | "dark" on <html> before first paint (no flash).
     2. Without JavaScript, the prefers-color-scheme block below still applies,
        so the OS preference is honoured.
     3. An explicit data-theme always wins over the OS preference.

   ACCESSIBILITY
   Verified with tools/check_contrast.py — every functional pair meets WCAG AA
   in both modes. Re-run that script after changing any value here.

   Three tokens deliberately differ from the original project palette, because
   the originals fall below AA and the project also requires AA:
     --text-muted  (light)  #8A8A8E -> #6A6A6E   (was 3.29:1 on --bg-base)
     --text-muted  (dark)   #7A7A7E -> #8A8A8E   (was 4.27:1 on --bg-surface)
     --accent-text (light)  #6E7075 -> #6A6C71   (was 4.39:1 on --bg-surface)
   The original greys are not discarded: #8A8A8E / #7A7A7E become
   --border-strong, where the applicable bar is the 3:1 component-boundary one,
   and #6E7075 remains --silver-accent-end for gradient fills.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Light mode (default)
   -------------------------------------------------------------------------- */

:root {
  color-scheme: light;

  /* Surfaces */
  --bg-base: #fafafa;
  --bg-surface: #f1f1f2;
  --bg-elevated: #ffffff;

  /* Text */
  --text-primary: #111113;
  --text-secondary: #4a4a4e;
  --text-muted: #6a6a6e;

  /* Borders */
  --border-subtle: #e1e1e3;   /* decorative dividers, card edges */
  --border-strong: #8a8a8e;   /* form and control boundaries (>=3:1) */

  /* Metallic silver accent */
  --silver-accent-start: #c7c9cc;
  --silver-accent-mid: #9ea1a6;
  --silver-accent-end: #6e7075;

  /* Accent applied to text: contrast-checked, not a raw gradient stop. */
  --accent-text: #6a6c71;
  --focus-ring: #6a6c71;

  /* Ink that sits on top of a silver fill. */
  --on-accent: #111113;

  /* Maximum-contrast moments (logo lockups, key headline words) — the only
     places true black/white is allowed, never for large surfaces. */
  --contrast-max: #000000;

  /* Plate for artwork we did not draw and cannot recolour: other companies'
     logos, and the black line-art illustrations. Both assume a light ground,
     and most of the logos are dark ink on transparency — on a dark surface
     they disappear entirely rather than merely looking wrong.

     THIS IS THE SAME VALUE IN BOTH THEMES, DELIBERATELY. It is the one token
     that must not flip: flipping it is the bug it exists to prevent. The
     surrounding card still carries the theme, so the plate reads as part of
     the image rather than as a light patch in a dark page. */
  --artwork-plate: #ffffff;

  /* The plate behind artwork an operator has uploaded AS the dark-mode half of
     a picture. It does not flip either, and for the mirror-image reason: that
     image is only ever shown in dark mode, so a light plate behind it would
     flash white while it loads and would show through anything transparent in
     it. Used only by .destination-card__media--dark, which exists only when a
     dark half has been uploaded — with none, the card emits one picture on the
     ordinary plate exactly as it always has. */
  --artwork-plate-dark: #0b0b0c;

  /* Shine sweep overlay for the metallic hover effect. */
  --silver-shine: rgba(255, 255, 255, 0.55);

  /* Shadows: neutral, low-alpha, so surfaces lift without a colour cast. */
  --shadow-sm: 0 1px 2px rgba(17, 17, 19, 0.05);
  --shadow: 0 4px 16px rgba(17, 17, 19, 0.08);
  --shadow-lg: 0 16px 48px rgba(17, 17, 19, 0.12);

  /* Which logo file the header/footer should show. */
  --logo-src: url("../images/logo/logo-light-360.webp");
}

/* --------------------------------------------------------------------------
   Dark mode
   Applied when the OS prefers dark AND the user has not explicitly chosen
   light. Keeps no-JS visitors on the right mode.
   -------------------------------------------------------------------------- */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --bg-base: #0b0b0c;
    --bg-surface: #151517;
    --bg-elevated: #1d1d20;

    --text-primary: #f5f5f6;
    --text-secondary: #b4b4b8;
    --text-muted: #8a8a8e;

    --border-subtle: #2a2a2d;
    --border-strong: #6a6a6e;

    --silver-accent-start: #e8e9eb;
    --silver-accent-mid: #b8babe;
    --silver-accent-end: #7c7e83;

    --accent-text: #b8babe;
    --focus-ring: #b8babe;

    --on-accent: #111113;
    --contrast-max: #ffffff;

    --silver-shine: rgba(255, 255, 255, 0.28);

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
    --shadow-lg: 0 16px 48px rgba(0, 0, 0, 0.6);

    --logo-src: url("../images/logo/logo-dark-360.webp");
  }
}

/* An explicit choice wins over the OS preference, in both directions. */
:root[data-theme="dark"] {
  color-scheme: dark;

  --bg-base: #0b0b0c;
  --bg-surface: #151517;
  --bg-elevated: #1d1d20;

  --text-primary: #f5f5f6;
  --text-secondary: #b4b4b8;
  --text-muted: #8a8a8e;

  --border-subtle: #2a2a2d;
  --border-strong: #6a6a6e;

  --silver-accent-start: #e8e9eb;
  --silver-accent-mid: #b8babe;
  --silver-accent-end: #7c7e83;

  --accent-text: #b8babe;
  --focus-ring: #b8babe;

  --on-accent: #111113;
  --contrast-max: #ffffff;

  --silver-shine: rgba(255, 255, 255, 0.28);

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
  --shadow-lg: 0 16px 48px rgba(0, 0, 0, 0.6);

  --logo-src: url("../images/logo/logo-dark-360.webp");
}

/* --------------------------------------------------------------------------
   Derived gradients
   Defined once, after the mode blocks, so both modes inherit them and the
   stops resolve to whichever palette is active.
   -------------------------------------------------------------------------- */

:root {
  /* Decorative sweep — full three-stop range. Never place text on this;
     the end stop is too dark in light mode for AA body text. */
  --silver-gradient: linear-gradient(
    135deg,
    var(--silver-accent-start) 0%,
    var(--silver-accent-mid) 50%,
    var(--silver-accent-end) 100%
  );

  /* Button and chip fills — start->mid only, so --on-accent ink stays at or
     above 7.2:1 across the whole fill in both modes. */
  --silver-gradient-fill: linear-gradient(
    135deg,
    var(--silver-accent-start) 0%,
    var(--silver-accent-mid) 100%
  );

  /* Hairline rule used for section dividers and underlines. */
  --silver-gradient-rule: linear-gradient(
    90deg,
    transparent 0%,
    var(--silver-accent-mid) 50%,
    transparent 100%
  );

  /* Moving highlight for the shine-sweep hover effect (see animations.css). */
  --silver-shine-sweep: linear-gradient(
    115deg,
    transparent 0%,
    transparent 35%,
    var(--silver-shine) 50%,
    transparent 65%,
    transparent 100%
  );
}

/* --------------------------------------------------------------------------
   Mode transition
   Only the properties that actually change colour are transitioned; a blanket
   `* { transition: all }` would drag every layout change through 250ms too.
   The class is removed by theme-init.js on first paint so the initial render
   is instant, and re-added once the page is interactive.
   -------------------------------------------------------------------------- */

/* TWO ELEMENTS, NOT EVERY ELEMENT.

   This selector was `.theme-transition *`, which on the company editor is
   3,024 elements, each interpolating five colour properties for 250ms. That is
   fifteen thousand simultaneous animations, and it is why switching mode felt
   like the page was working its way down the document rather than changing.
   Measured: 90ms of blocked scripting before a single frame was even drawn.

   The whole-page cross-fade is done by the browser's view transition instead —
   see theme-toggle.js. That snapshots the page before and after and fades one
   image into the other on the compositor, so the cost is the same whether the
   page holds ten elements or ten thousand.

   What is left here is the fallback for a browser without view transitions.
   The page's own background and text colour still ease; everything else
   changes at once, which is instant and honest rather than slow and smeared. */
.theme-transition,
.theme-transition body {
  transition:
    background-color var(--duration-fast) var(--ease-out),
    color var(--duration-fast) var(--ease-out);
}

/* The cross-fade itself. Short: the complaint this answers was that switching
   mode felt slow, and replacing a slow animation with a shorter slow animation
   would be answering it badly.

   pointer-events: none is not a detail. While a view transition runs, the
   browser paints its snapshots in a layer over the live page — so for the
   length of the animation every click lands on a picture of the page instead
   of the page. A quarter of a second of a dead admin, on every theme change,
   is a worse bargain than the fade is worth. Turning it off here lets a press
   during the fade reach what is underneath, which is already the real page. */
::view-transition {
  pointer-events: none;
}

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: var(--duration-fast);
  animation-timing-function: var(--ease-out);
}
