/* ============================================================
   Familix — Variant 8 "Geode"
   Variant 7 (Quartz, light) and variant 6 (Obsidian, dark) as one
   build with a switch between them.

     :root                     Quartz   — light  ← DEFAULT
     :root[data-theme="dark"]  Obsidian — dark

   Light sits on plain :root deliberately: it is what renders with no
   JavaScript and no stored preference. Dark is opt-in.

   `components.css` and `app.css` contain NO colour literals — every
   colour resolves through a token declared here. Switching theme
   therefore never touches component CSS, and adding a third theme
   is one more block in this file and nothing else.
   ============================================================ */

/* ------------------------------------------------------------
   QUARTZ — light · the default
   ------------------------------------------------------------ */
:root {
  color-scheme: light;

  /* Brand — the deep end carries text and icons on a light ground */
  --brand-400: #4054d8;
  --brand-500: #5c72f5;
  --brand-600: #7488fa;
  --brand-700: #8fa0fc;
  --teal-400: #0f9e97;
  --teal-600: #5fd8d0;

  /* Ground */
  --bg: #f6f7fb;
  --bg-2: #eef0f7;
  --panel: #ffffff;

  /* Surfaces — raised means lighter in BOTH themes. That is why these
     are two token sets and not one inversion filter. */
  --glass: #ffffff;
  --glass-2: #f2f4fb;
  --row-hover: #f4f6fd;
  --sunken: rgba(19, 26, 46, 0.035);
  --sunken-2: #f7f9fd;
  --sunken-3: rgba(19, 26, 46, 0.04);
  --tint: rgba(19, 26, 46, 0.025);
  --tint-2: rgba(19, 26, 46, 0.03);
  --window-bg: linear-gradient(165deg, #ffffff, #fbfcfe);
  --footer-bg: #eef0f7;
  --nav-bg: rgba(246, 247, 251, 0.82);
  --backdrop: rgba(19, 26, 46, 0.45);

  /* Lines */
  --stroke: rgba(19, 26, 46, 0.12);
  --stroke-2: rgba(19, 26, 46, 0.22);
  --hairline: rgba(19, 26, 46, 0.07);
  --grid-line: rgba(19, 26, 46, 0.035);

  /* Controls */
  --input-bg: #ffffff;
  --input-bg-focus: #ffffff;
  --track: rgba(19, 26, 46, 0.12);
  --focus-ring: 0 0 0 3px rgba(92, 114, 245, 0.22);

  /* Text */
  --text: #131a2e;
  --text-muted: #515c7a;
  --text-dim: #7b859e;
  --on-accent: #ffffff;   /* sits on a gradient chip */
  --on-brand: #ffffff;    /* sits on the brand button */
  --on-danger: #ffffff;

  /* Semantic — never the brand hue */
  --success: #0f9d63;  --success-bg: rgba(15, 157, 99, 0.11);
  --warning: #b45309;  --warning-bg: rgba(180, 83, 9, 0.10);
  /* Text sitting ON `--warning-bg`, not on the page ground. `--warning` clears
     4.5:1 against white but only 4.35:1 once the amber wash is behind it, so a
     warning chip needs the darker step. v1's `.badge--warn` used this same
     amber-800 for the same reason. */
  --warning-strong: #92400e;
  --danger:  #dc2626;  --danger-bg:  rgba(220, 38, 38, 0.09);
  --danger-hover: #b91c1c;
  --danger-border: rgba(220, 38, 38, 0.40);
  --danger-ring: 0 0 0 3px rgba(220, 38, 38, 0.16);
  --success-border: rgba(15, 157, 99, 0.28);
  --info-bg: rgba(92, 114, 245, 0.11);
  --info-border: rgba(92, 114, 245, 0.30);
  --violet: #6d4aff;

  /* Gradients — brand runs deep→deeper so the white label survives */
  --grad-brand:  linear-gradient(135deg, #5c72f5, #4054d8);
  --grad-mark:   linear-gradient(140deg, #4054d8, #0f9e97);
  --grad-text:   linear-gradient(110deg, #4054d8 15%, #0f9e97 85%);
  --grad-rule:   linear-gradient(90deg, #4054d8, #0f9e97);
  --grad-active: linear-gradient(120deg, rgba(92, 114, 245, 0.30), rgba(47, 212, 200, 0.10));
  --grad-active-border: rgba(92, 114, 245, 0.42);
  --grad-cta:    linear-gradient(120deg, rgba(92, 114, 245, 0.14), rgba(47, 212, 200, 0.06));
  --grad-quote:  linear-gradient(140deg, rgba(92, 114, 245, 0.16), rgba(47, 212, 200, 0.06));
  --grad-quote-border: rgba(92, 114, 245, 0.28);

  /* Ambient field — alpha baked in, ~40% of the dark theme's strength.
     A saturated blur at the dark opacity tints body text on paper. */
  --field-1: rgba(92, 114, 245, 0.18);
  --field-2: rgba(95, 216, 208, 0.10);
  --field-3: rgba(143, 160, 252, 0.12);

  /* ---- Companion role badges (request 131 §6) ----
     One hue per role. Each pair is a tint background with a same-hue
     foreground, and every one is measured at 11.5px — normal text, so 4.5:1
     applies to all eight. Light: pale tint, ink-dark text. */
  --role-friend-bg:    #e6eafc;  --role-friend-fg:    #2f41bd;
  --role-family-bg:    #d9f3f0;  --role-family-fg:    #0d5f5a;
  --role-colleague-bg: #fbeed2;  --role-colleague-fg: #7a4e00;
  --role-partner-bg:   #fbe4ed;  --role-partner-fg:   #98204f;
  --role-coach-bg:     #ddf1e0;  --role-coach-fg:     #1d6127;
  --role-guide-bg:     #dcecf9;  --role-guide-fg:     #10556f;
  --role-customer-bg:  #eee3fa;  --role-customer-fg:  #61329b;
  --role-other-bg:     #e8eaf1;  --role-other-fg:     #434a61;
  /* "you are" (request 139). Orange is the one hue the eight roles leave free —
     blue, teal, amber, pink, green, sky, purple and grey are all taken — so the
     badge reads as a different KIND of label, not a ninth role. */
  --role-self-bg:      #ffe1cf;  --role-self-fg:      #8f3410;

  /* Elevation — on paper, depth reads through opacity, not black */
  --shadow-sm: 0 1px 2px rgba(19, 26, 46, 0.07);
  --shadow-md: 0 8px 24px rgba(19, 26, 46, 0.09);
  --shadow-lg: 0 24px 56px rgba(19, 26, 46, 0.14);
  --glow: 0 8px 24px rgba(92, 114, 245, 0.28);
  --glow-hover: 0 10px 28px rgba(92, 114, 245, 0.34);

  /* ---- Navigation rail ----
     Inked in BOTH themes. Under Quartz it is a slab that stops the
     white rail and the white content column merging into each other;
     under Obsidian it becomes glass over the page. */
  --rail: #151c33;
  /* Opaque twin of the rail, for the mobile drawer, which floats over content
     where glass is unreadable (bug 0018). */
  --rail-solid: #151c33;
  --rail-2: #1d2645;
  --rail-border: transparent;
  --rail-text: #e6e9f5;
  --rail-muted: #a2abc6;
  --rail-dim: #79829e;
  --rail-stroke: rgba(255, 255, 255, 0.10);
  --rail-stroke-2: rgba(255, 255, 255, 0.18);
  --rail-hover: rgba(255, 255, 255, 0.07);
  --rail-active: linear-gradient(120deg, rgba(92, 114, 245, 0.55), rgba(15, 158, 151, 0.28));
  --rail-active-border: rgba(128, 147, 255, 0.55);
  --rail-active-text: #ffffff;
  --rail-active-icon: #7ee8e0;
  --rail-av: linear-gradient(135deg, #8093ff, #2fd4c8);
  --rail-av-fg: #0d1220;
  --rail-focus: #7ee8e0;

  /* ---- Non-colour: identical in both themes ---- */
  --r-xs: 4px;
  --r-sm: 6px;
  --r-md: 8px;
  --r-lg: 12px;
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
    Arial, "Noto Sans Hebrew", sans-serif;
  --mono: "SF Mono", "Cascadia Mono", Consolas, "Liberation Mono", monospace;
  --container: 1240px;
}

/* ------------------------------------------------------------
   OBSIDIAN — dark · opt-in
   Only colour is redeclared. Radii, type and layout are inherited
   from the block above, which keeps the two modes in step.
   ------------------------------------------------------------ */
:root[data-theme="dark"] {
  color-scheme: dark;

  /* Same hues; ramp reversed so the light end carries text on ink */
  --brand-400: #8093ff;
  --brand-500: #5c72f5;
  --brand-600: #4356d6;
  --brand-700: #3543b4;
  --teal-400: #2fd4c8;
  --teal-600: #14a8a0;

  --bg: #0a0e1c;
  --bg-2: #0e1428;
  --panel: #121a30;

  --glass: rgba(255, 255, 255, 0.04);
  --glass-2: rgba(255, 255, 255, 0.07);
  --row-hover: rgba(255, 255, 255, 0.04);
  --sunken: rgba(0, 0, 0, 0.18);
  --sunken-2: rgba(0, 0, 0, 0.16);
  --sunken-3: rgba(0, 0, 0, 0.24);
  --tint: rgba(255, 255, 255, 0.02);
  --tint-2: rgba(255, 255, 255, 0.03);
  --window-bg: linear-gradient(165deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.02));
  --footer-bg: rgba(0, 0, 0, 0.3);
  --nav-bg: rgba(10, 14, 28, 0.78);
  --backdrop: rgba(4, 6, 16, 0.74);

  --stroke: rgba(255, 255, 255, 0.09);
  --stroke-2: rgba(255, 255, 255, 0.17);
  --hairline: rgba(255, 255, 255, 0.05);
  --grid-line: rgba(255, 255, 255, 0.025);

  --input-bg: rgba(0, 0, 0, 0.24);
  --input-bg-focus: rgba(0, 0, 0, 0.34);
  --track: rgba(255, 255, 255, 0.1);

  --text: #e8ecf7;
  --text-muted: #9aa5c4;
  --text-dim: #6b7699;
  --on-accent: #0a0e1c;
  --on-danger: #24070a;

  --success: #34d399;  --success-bg: rgba(52, 211, 153, 0.13);
  --warning: #fbbf24;  --warning-bg: rgba(251, 191, 36, 0.13);
  /* On ink the light amber is already the readable end of the ramp (6.08:1 on
     the chip), so the strong step stays where it is rather than going darker. */
  --warning-strong: #fbbf24;
  --danger:  #f87171;  --danger-bg:  rgba(248, 113, 113, 0.13);
  --danger-hover: #fb8a8a;
  --danger-border: rgba(248, 113, 113, 0.45);
  --danger-ring: 0 0 0 3px rgba(248, 113, 113, 0.18);
  --success-border: rgba(52, 211, 153, 0.28);
  --info-bg: rgba(92, 114, 245, 0.15);
  --info-border: rgba(92, 114, 245, 0.30);
  --violet: #a78bfa;

  --grad-brand:  linear-gradient(135deg, #8093ff, #4356d6);
  --grad-mark:   linear-gradient(140deg, #8093ff, #2fd4c8);
  --grad-text:   linear-gradient(110deg, #8093ff 15%, #2fd4c8 85%);
  --grad-rule:   linear-gradient(90deg, #8093ff, #2fd4c8);
  --grad-active: linear-gradient(120deg, rgba(92, 114, 245, 0.32), rgba(47, 212, 200, 0.12));
  --grad-active-border: rgba(92, 114, 245, 0.4);
  --grad-cta:    linear-gradient(120deg, rgba(92, 114, 245, 0.18), rgba(47, 212, 200, 0.07));
  --grad-quote:  linear-gradient(140deg, rgba(92, 114, 245, 0.24), rgba(47, 212, 200, 0.08));
  --grad-quote-border: rgba(92, 114, 245, 0.32);

  --field-1: rgba(92, 114, 245, 0.30);
  --field-2: rgba(20, 168, 160, 0.16);
  --field-3: rgba(53, 67, 180, 0.22);

  /* Role badges on ink: the tint goes translucent so it sits on the page
     instead of glowing, and the text lightens to carry the contrast. */
  --role-friend-bg:    rgba(128, 147, 255, 0.18); --role-friend-fg:    #aeb9ff;
  --role-family-bg:    rgba(47, 212, 200, 0.16);  --role-family-fg:    #6fded4;
  --role-colleague-bg: rgba(240, 180, 70, 0.16);  --role-colleague-fg: #f0c473;
  --role-partner-bg:   rgba(244, 114, 160, 0.16); --role-partner-fg:   #f79cba;
  --role-coach-bg:     rgba(90, 200, 110, 0.16);  --role-coach-fg:     #89dd9a;
  --role-guide-bg:     rgba(90, 180, 235, 0.16);  --role-guide-fg:     #8fcdf2;
  --role-customer-bg:  rgba(180, 130, 240, 0.16); --role-customer-fg:  #cba9f7;
  --role-other-bg:     rgba(255, 255, 255, 0.10); --role-other-fg:     #c4ccdf;
  --role-self-bg:      rgba(255, 146, 84, 0.18);  --role-self-fg:      #ffb689;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 8px 24px rgba(0, 0, 0, 0.4);
  --shadow-lg: 0 24px 56px rgba(0, 0, 0, 0.55);
  --glow: 0 0 32px rgba(92, 114, 245, 0.35);
  --glow-hover: 0 0 44px rgba(92, 114, 245, 0.5);

  /* Glass here rather than a slab: the page is already dark, so the
     rail no longer has to hold its own edge. */
  --rail: rgba(0, 0, 0, 0.28);
  /* The same colour the desktop rail resolves to over the page, made opaque so
     the drawer covers what is behind it (bug 0018). */
  --rail-solid: #070a14;
  --rail-2: rgba(255, 255, 255, 0.04);
  --rail-border: var(--stroke);
  --rail-text: var(--text);
  /* NOT var(--text-muted) (task 0149b). In dark the rail is glass —
     rgba(0,0,0,0.28) over the page — so it composites LIGHTER than the light
     theme's solid #151c33 rail, and the page's muted colour loses the contrast
     it has everywhere else. Sampled from the painted pixels: #9aa5c4 on the
     composited rail is 3.67:1, under AA for the 10.5px group titles that were
     already using it and for the brand suffix added here. #b3bcd4 measures
     4.92:1 and still reads a step below --rail-text. */
  --rail-muted: #b3bcd4;
  --rail-dim: var(--text-dim);
  --rail-stroke: var(--stroke);
  --rail-stroke-2: var(--stroke-2);
  --rail-hover: var(--glass);
  --rail-active: var(--grad-active);
  --rail-active-border: rgba(92, 114, 245, 0.42);
  --rail-active-text: var(--text);
  --rail-active-icon: var(--teal-400);
  --rail-av: var(--grad-mark);
  --rail-av-fg: var(--on-accent);
  --rail-focus: var(--teal-400);
}

/* Cross-fade only after load, so switching animates but the first
   paint does not. theme.js adds .theme-ready on DOMContentLoaded. */
.theme-ready body,
.theme-ready .nav,
.theme-ready .topbar,
.theme-ready .side,
.theme-ready .panel,
.theme-ready .stat,
.theme-ready .trip,
.theme-ready .auth-card,
.theme-ready .window {
  transition: background-color 0.22s ease, border-color 0.22s ease, color 0.22s ease;
}
@media (prefers-reduced-motion: reduce) {
  .theme-ready * { transition: none !important; }
}
