/**
 * Lion portal theme system — CSS only, no JavaScript.
 *
 * Model: three states, one source of truth.
 *
 *   auto  (default)  → :root:has(#theme-auto:checked)   follows the OS / browser preference
 *   dark             → :root:has(#theme-dark:checked)   explicit choice, pinned
 *   light            → :root:has(#theme-light:checked)  explicit choice, pinned
 *
 * All three are radios in the same group, so exactly one is always selected and the control never
 * changes shape: "Auto" is an option you can see and return to, not a button that appears once you
 * have overridden the system.
 *
 * Every colour token in styles.css is declared once, with light-dark(). light-dark() resolves
 * against the *computed* color-scheme, so selecting a theme flips a single declaration per state
 * and no colour value is duplicated anywhere. That is also why this file must be loaded before
 * styles.css.
 *
 * Image values are the one exception: light-dark() accepts <color> only. Image values (gradients)
 * land in Safari 27 (2026-09-14, WebKit bug 309689) and are not available in Safari 26.x, which is
 * still inside the "latest four Safari versions" support window. Safari 26.x drops the declaration
 * instead of ignoring it, and on a `background-clip: text` element that combination
 * (background-image: none + `-webkit-text-fill-color: transparent`) renders the text invisible.
 * The gradient/grid tokens below are therefore declared per state rather than via light-dark().
 */

:root {
  color-scheme: light dark;

  /* Gradient + grid tokens: fallback path for Safari 26.x (see note above).
   * The two heading pairs are kept separate because the shipped dark theme ends .hero h1 at #888
   * and .docs-content h1 at #777; collapsing them would be a silent design change. */
  --heading-gradient-from: #111111;
  --heading-gradient-to: #777777;
  --hero-gradient-from: #111111;
  --hero-gradient-to: #777777;
  --grid-line-color: #f5f5f5;
}

/*
 * The dark gradient/grid values, declared once and referenced by both selectors below, so the
 * "no duplicated colour values" rule of this file still holds for the fallback path.
 */
:root {
  --_dark-heading-gradient-from: #ffffff;
  --_dark-heading-gradient-to: #777777;
  --_dark-hero-gradient-from: #ffffff;
  --_dark-hero-gradient-to: #888888;
  --_dark-grid-line-color: #0b0b0b;
}

/*
 * Every state is keyed twice: on the radio (`:has()`) for a visitor without JavaScript, and on the
 * `data-theme` attribute that src/components/ThemeInit.astro sets before the first paint. The
 * attribute matters because on a reload the radios do not exist yet, and it is the only way the
 * choice can survive a navigation on a static MPA.
 *
 * System-resolved dark — only while "Auto" is the selected option. An explicit light or dark
 * choice is never touched by the OS preference.
 */
@media (prefers-color-scheme: dark) {
  :root:has(#theme-auto:checked),
  :root[data-theme='auto'] {
    --heading-gradient-from: var(--_dark-heading-gradient-from);
    --heading-gradient-to: var(--_dark-heading-gradient-to);
    --hero-gradient-from: var(--_dark-hero-gradient-from);
    --hero-gradient-to: var(--_dark-hero-gradient-to);
    --grid-line-color: var(--_dark-grid-line-color);
  }
}

/*
 * Explicit choices. Same specificity as the system block above, declared after it, so an explicit
 * choice always wins regardless of what the OS says.
 */
:root:has(#theme-auto:checked),
:root[data-theme='auto'] {
  color-scheme: light dark;
}

:root:has(#theme-dark:checked),
:root[data-theme='dark'] {
  color-scheme: dark;

  --heading-gradient-from: var(--_dark-heading-gradient-from);
  --heading-gradient-to: var(--_dark-heading-gradient-to);
  --hero-gradient-from: var(--_dark-hero-gradient-from);
  --hero-gradient-to: var(--_dark-hero-gradient-to);
  --grid-line-color: var(--_dark-grid-line-color);
}

:root:has(#theme-light:checked),
:root[data-theme='light'] {
  color-scheme: light;
}

/* ----------------------------------------------------------------------------------------------
 * Theme switch (rendered by src/components/TopNav.astro)
 *
 * Three options — Auto, light, dark — as one radio group, so the current choice is always visible
 * and always exactly one. The checked label is the selection: highlight border plus a tinted fill.
 * -------------------------------------------------------------------------------------------- */

.theme-switch {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-left: 16px;
}

/* Visually hidden but focusable: the labels carry the affordance. */
.theme-switch input[type='radio'] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.theme-switch label {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 32px;
  padding: 0;
  width: 32px;
  border: 1px solid var(--border-color);
  border-radius: var(--border-radius-circle, 50%);
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  transition: color 0.2s, border-color 0.2s, background-color 0.2s;
}

/* "Auto" is a word rather than an icon, so it gets a pill instead of a circle. The word is
 * smaller than the surrounding labels on purpose: it has to sit inside the same 32px row. */
.theme-switch label[for='theme-auto'] {
  width: auto;
  padding: 0 8px;
  border-radius: 999px;
  font-size: 0.625rem;
  line-height: 1;
}

.theme-switch label:hover {
  color: var(--text-primary);
}

.theme-switch input[type='radio']:checked + label {
  color: var(--text-primary);
  border-color: var(--highlight-color);
  background: color-mix(in srgb, var(--highlight-color) 18%, transparent);
}

.theme-switch input[type='radio']:focus-visible + label {
  outline: 2px solid var(--focus-border-color-outer, currentColor);
  outline-offset: 2px;
}

/* Contrast themes replace the palette; hand the switch over to the system colours. */
@media (forced-colors: active) {
  .theme-switch label {
    border-color: ButtonText;
  }

  .theme-switch input[type='radio']:checked + label {
    border-color: Highlight;
    color: Highlight;
  }

  .theme-switch input[type='radio']:focus-visible + label {
    outline-color: Highlight;
  }
}
