/* ABOUTME: Reusable dark theme — scope to a surface with class="theme-dark". */

/* ABOUTME: Used for the in-workout screen (light home, dark in-workout). */

/*
  Overrides the design tokens to dark values for any subtree marked .theme-dark.
  The gray ramp is INVERTED: in the light system low grays are light (fills) and
  high grays are dark (text); under dark, low grays become dark surfaces and high
  grays become light text — so token-driven elements (var(--gray-100) fills,
  var(--gray-700) text) flip correctly with no per-element edits.
  Brand --orange is unchanged (luminous accent against the dark).
*/
.theme-dark {
  /* Espresso-warm dark, "high relief" (Jul 2026): the ROOM stays deep
     (#16120E, the identity) and the lift is spent entirely on the cards -
     paper steps to 1.18:1 vs bg, hairlines to 1.45:1 on paper, muted text
     to 5.5:1 - so the ledger separates by surface instead of by shadows
     the near-black ground can't show. */
  --bg: #16120E;
  --surface: #2A2118;
  --surface-2: #362B1F;
  --border: #4E3F2D;
  --text: #F5F0E9;
  --text-secondary: #C8BDB0;
  --text-muted: #A2968A;

  /* Inverted warm-neutral gray ramp, shifted with the raised card surfaces */
  --gray-50: #2A2118;
  --gray-100: #362B1F;
  --gray-200: #4E3F2D;
  --gray-300: #5A4A36;
  --gray-400: #6E6250;
  --gray-500: #A2968A;
  --gray-600: #B3A99C;
  --gray-700: #C8BDB0;
  --gray-800: #DFD7CC;
  --gray-900: #F5F0E9;

  /* Warm-editorial aliases flip with the room; accent lifts for dark contrast.
     These MUST be re-declared rather than inherited: a custom property whose
     value is var(--x) is substituted where it is DECLARED, so the :root copy
     computed against the light --surface/--text and froze there. Every alias
     below is in this file for that reason, not for a different value. */
  --cream: var(--bg);
  --paper: var(--surface);

  /* Deliberately NOT --surface-2. --paper-2 is the RECESSED partner of
     --paper - a segmented track under its sliding thumb, a pressed row, an
     inset well - and every one of its ~90 uses is a background of that kind.
     In light it sits a step DOWN from the card (#F9F0E1 under #FFFEFB), so on
     dark it has to step down too. Aliased to the raised --surface-2 it stepped
     UP instead, which inverted every track/thumb pair in the app: the thumb
     came out darker than its own track and read as a hole punched through it
     rather than a pill resting on it. Between the card and the room, nearer
     the card, so a control still reads as sitting on the card it is part of. */
  --paper-2: #201A12;
  --rule: var(--border);
  --ink: var(--text);
  --ink-soft: var(--text-secondary);
  --ink-faint: var(--text-muted);

  /* Same freeze, same fix: these alias the hues re-declared further down. */
  --success-500: var(--green);
  --error-500: var(--red);
  --warning-500: var(--yellow);

  /* The .ps-page canvas glow, keyed to the dark ground (see the light copy for
     why the fade stop repeats the hue at zero alpha instead of `transparent`).
     Held much tighter to --bg than the light pair is to --cream: the same
     absolute step that reads as a warm lift on cream reads as a gray smudge on
     a near-black ground, where the eye resolves low-end differences far more
     finely. Six points up, not fourteen. */
  --page-glow: #1C1710;
  --page-glow-fade: rgb(28 23 16 / 0%);

  /* --orange stays inherited (default or the gym's branded primary - dark
     must follow white-label brands), so washes/glows derive from it with
     color-mix instead of hardcoding a hex that drifts from the brand. */
  --accent-ink: #F0956A;
  --goal-over-ink: #F2736A;
  --accent-wash: color-mix(in srgb, var(--orange) 20%, transparent);
  --wash: color-mix(in srgb, var(--orange) 20%, transparent);
  --accent-rule: color-mix(in srgb, var(--orange) 35%, transparent);

  /* Yesterday recap tile: same "tint just above the raised paper" recipe as
     --sage-wash below, keyed off the brand orange since the light tile reads
     peachy-cream. */
  --gym-stat-wash-from: color-mix(in srgb, var(--orange) 8%, transparent);
  --gym-stat-wash-to: color-mix(in srgb, var(--orange) 14%, transparent);
  --gym-stat-rule: color-mix(in srgb, var(--orange) 28%, transparent);

  /* Quiet primary on dark: same recipe inverted - the wash mixes toward the
     dark ground instead of white, the ink label resolves light via --text,
     and the border brightens to the full brand orange for rank. Statics
     first for pre-16.2 WebKit (no color-mix); @supports below upgrades. */
  --btn-primary-bg: #552B16;
  --btn-primary-bg-hover: #683319;
  --btn-primary-bg-active: #75391B;

  /* Re-declared (not inherited): var(--text) inside a custom property resolves
     where the property is DECLARED, so the :root copy froze the light ink. */
  --btn-primary-ink: var(--text);
  --btn-primary-border: var(--orange);
  --btn-primary-icon: #F0956A;
  --sage: #8FAF86;
  --sage-wash: rgb(143 175 134 / 15%);

  /* --amber ink is redeclared below in the status/identity block; this is a
     second, distinct wash from the same recipe (amber's own rgb at 15%),
     because dashboard.css's class-schedule chips need a fill separate from
     --amber-light (the ramp's 50-step tint, tuned for a different use). */
  --amber-wash: rgb(240 176 60 / 15%);

  /* Score grades, same recipe as --sage/--sage-wash: the dot lifts, the wash
     becomes a tint keyed just above the raised paper. Solid sits a step below
     Excellent in both themes so the two greens stay tellable apart.
     --grade-steady re-declares var(--yellow) because a custom property that
     names another one resolves where it is DECLARED - inherited, it would
     have frozen the light yellow. */
  --grade-solid: #5E8455;  --grade-solid-wash: rgb(94 132 85 / 16%);
  --grade-steady: var(--yellow); --grade-steady-wash: rgb(243 195 74 / 14%);

  /* Light status/accent tint fills → dark tints keyed ABOVE the raised paper
     (so var(--primary-50) etc. read as tinted chips on the cards, not holes).
     Accent 500/600 stay vivid. */
  --primary-50: #3A2D1E;
  --primary-100: #453423;
  --primary-200: #523B26;
  --orange-light: #3A2D1E;
  --success-50: #263528;
  --success-100: #2E4031;
  --error-50: #3C2823;
  --error-100: #462E28;

  /* Award/celebration palette, same recipe: the peach wash keys just above the
     raised paper so an achievement card reads as a warm tint on the ledger
     rather than a light hole punched in it, and the ink flips to a light peach
     (the light-mode #B56A3F is a dark ink and vanishes against the tint). */

  /* from is the LIGHTER end in both themes. These are the two stops of a
     135deg gradient, so swapping them turns the light around: light mode runs
     bright-to-dim from the top-left, and the first cut of these ran dim-to-
     bright, lighting the card from the opposite corner to every other one. */
  --award-wash-from: #4A3527;
  --award-wash-to: #3E2E22;
  --award-rule: #5E4230;
  --award-ink: #F0AE85;

  /* Roll call, dark: the same espresso depth as the award wash but held on the
     golden side, since the light card is gold rather than peach. `from` is the
     lighter stop here too - the gradient runs 135deg in both rooms. */
  --roll-call-wash-from: #453421;
  --roll-call-wash-to: #392B1B;
  --roll-call-rule: #5A4429;

  /* Win-emote pill: resting fill just blends into the card (--surface-2 is
     the app's own "one step up from paper" tone); the hover/active highlight
     reuses the achievement wash - the exact "warm tint on the ledger" this
     pill wants when it lights up. */
  --award-pill-bg: var(--surface-2);
  --award-pill-bg-hover: var(--award-wash-from);

  /* ===== Status + identity families, in fill/ink PAIRS =====
     These break in opposite directions if only half is done, which is why they
     are grouped by family here rather than by ramp. A `-light` wash left alone
     stays a pale chip glowing on the dark ledger; a 600/700 ink left alone goes
     dark-on-dark and vanishes. Each hue below therefore lifts (used as ink) and
     each wash darkens to a tint keyed just ABOVE the raised paper, so a badge
     reads as a tinted chip on the card instead of a hole punched in it. */
  --green: #5CC97E;      --green-light: #26352A;
  --red: #F2736A;        --red-light: #3C2825;
  --yellow: #F3C34A;     --yellow-light: #37301F;
  --purple: #A78BFA;     --purple-light: #322A40;
  --blue: #7BA9F7;       --blue-light: #232C3D;
  --indigo: #8B8DF5;     --indigo-light: #282A44;
  --teal: #3FD0BE;       --teal-light: #1E3833;
  --cyan: #3FCBE4;       --cyan-light: #1E353C;
  --amber: #F0B03C;      --amber-light: #38301D;

  /* Identity hues, same pairing (--sage/--sage-wash is above). */
  --violet: #A99EE0;     --violet-wash: #2E2A44;
  --steel: #8FB6D4;      --blue-wash: #24313D;
  --gold: #D9B65C;       --gold-wash: #3A3220;

  /* Ramp tails. The 50/100/200 fills are handled above; these are the mid and
     dark stops used as INK on them, so they run light on dark. */
  --success-200: #38513C;
  --success-300: #4E7A58;
  --success-400: #63A272;
  --success-600: #63C983;
  --success-700: #7FD79A;
  --success-800: #9AE0AF;
  --success-900: #B6E9C4;
  --error-200: #55322C;
  --error-600: #F2736A;
  --error-700: #F58C82;
  --warning-600: #EDA94A;
  --warning-700: #F0B963;

  /* --primary-300..600 are vivid oranges that already carry on the dark ground
     and stay put; only the dark rusts used as ink need to flip. */
  --primary-700: #F0956A;
  --primary-800: #F3A681;
  --primary-900: #F6B698;

  /* The default block header is a near-black espresso on light. Left alone it
     sits within a hair of the card and the header stops reading as a header, so
     it lifts just enough to keep the step (white label still ~8:1). */
  --block-default-from: #574636;
  --block-default-to: #43362C;

  /* Shadows read as glow/depth on dark */
  --shadow-sm: 0 1px 2px rgb(0 0 0 / 40%);
  --shadow: 0 2px 6px rgb(0 0 0 / 45%);
  --shadow-md: 0 6px 18px rgb(0 0 0 / 50%);
  --shadow-lg: 0 12px 32px rgb(0 0 0 / 55%);

  background: var(--bg);
  color: var(--text);

  /* Tell the engine this subtree is dark so form controls, the caret, and -
     crucially in the native shell - the software keyboard raised from inputs
     here render dark. WebKit keys the keypad's appearance off the focused
     element's color-scheme, not the app's (force-light) UI style, so the
     numeric keypad's rounded corners now blend into the dark room instead of
     revealing a hard light-on-dark seam. Templates stay light (no .theme-dark). */
  color-scheme: dark;
}

/* Brand-derived quiet-primary fills where WebKit has color-mix (16.2+). */
@supports (color: color-mix(in srgb, red, blue)) {
  .theme-dark {
    --btn-primary-bg: color-mix(in oklch, var(--orange) 32%, #14100D);
    --btn-primary-bg-hover: color-mix(in oklch, var(--orange) 40%, #14100D);
    --btn-primary-bg-active: color-mix(in oklch, var(--orange) 46%, #14100D);
  }
}

/* ===== Apple-native polish parity (Jun 8 2026) — depth/material on dark ===== */
.theme-dark {
  /* Specular flips to a brighter top rim-light on near-black (bolder) */
  --specular: inset 0 1px 0 rgb(255 255 255 / 12%);
  --hairline: color-mix(in srgb, var(--border) 85%, transparent);

  /* Two-light elevation, deeper/softer black on dark (bolder float + less negative spread) */
  --e1: 0 1px 2px rgb(0 0 0 / 45%), 0 10px 22px -8px rgb(0 0 0 / 55%);
  --e2: 0 2px 6px rgb(0 0 0 / 50%), 0 18px 38px -12px rgb(0 0 0 / 64%);
  --e3: 0 6px 18px rgb(0 0 0 / 55%), 0 30px 56px -16px rgb(0 0 0 / 70%);
  --e4: 0 12px 32px rgb(0 0 0 / 62%), 0 46px 80px -22px rgb(0 0 0 / 76%);

  /* Re-alias legacy names onto the dark ramp */
  --shadow-sm: var(--e1); --shadow: var(--e1);
  --shadow-md: var(--e2); --shadow-lg: var(--e3);
  --elev-1: var(--e1); --elev-2: var(--e2);

  /* Frosted material reads on the dark canvas */
  --material-surface: color-mix(in srgb, var(--surface) 90%, transparent);
}

/* Dark block/cards separate from --bg via rim + depth (no hard border) */
.theme-dark .wk-block,
.theme-dark .card {
  box-shadow: var(--specular), 0 0 0 1px rgb(255 255 255 / 8%), var(--e3);
}

/* Global table chrome hardcodes light fills that don't flip with the tokens
   (admin.css zebra-stripes even rows #f3f4f6, admin/application.css add hover
   fills) - invisible-ink over light text on any dark surface, e.g. the sets
   tables in the exercise history sheet. Rows keep their token-driven borders. */
.theme-dark tbody tr:nth-child(even):not(.disabled-row),
.theme-dark tbody tr:hover:not(.disabled-row) {
  background-color: transparent;
}

/* ===== Tokens declared on DESCENDANTS, not :root =====
   These need real selectors rather than lines in the .theme-dark block above.
   A custom property set on a descendant wins over the same property inherited
   from an ancestor no matter how the ancestor is themed, so adding them to
   .theme-dark { } looks right in the diff and changes nothing on screen. Each
   rule below therefore has to out-specify the element that declares them. */

/* section_nav.css declares these on body.viewing-client (0,1,1), which beats a
   bare .theme-dark (0,1,0) - hence both orderings, so it works whether the
   theme class lands on the body itself or on an ancestor. */
.theme-dark body.viewing-client,
body.viewing-client.theme-dark,
.theme-dark .viewing-client {
  --view-purple: #B47AE8;
  --view-purple-ink: #D9B8F2;
  --view-purple-wash: #2F2440;
  --view-purple-soft: #241C30;

  /* Same lift --award-rule takes above --award-wash-from/-to: a step lighter
     than the wash, still muted against the near-black room. */
  --view-purple-rule: #4B3A5C;
}

/* log_stack.css declares the check-in scale stops on .check-in-scale. The track
   is a saturated signal color, so these lift rather than invert. */
.theme-dark .check-in-scale {
  --scale-low: #E8705A;
  --scale-mid: #EDB44E;
  --scale-high: #8FBF7E;
}
