/* ============================================================
   main.css — design tokens and page-wide base styles.

   Loaded FIRST on every page (marketing and console alike). Owns:
     · the :root theme tokens (dark default + light-mode overrides)
     · the body base (font stack, page sizing)
     · the shared shell primitives every page builds on: .stage,
       .pass-panel / .pass-panel__inner / .pass-logo (the left panel used by
       the marketing pages AND the console rail), and .visually-hidden
   Anything specific to the marketing pages lives in marketing.css; anything
   console-only lives in console.css + one file per console view.
   ============================================================ */

/* ---- Theme tokens ----
   The console supports two modes. Dark is the default and is what every page
   gets with no attribute set; light is opted into per tenant and switched on by
   `data-mode="light"` on <html> (see the MODE card in SETTINGS).

   NOTE the four role tokens below name a ROLE, not a literal color: --ink is
   "the surface", --paper/-soft/-dim are "text, in three weights". Light mode
   swaps their values, so in light mode --ink holds cream and --paper holds
   brown. Every rule in this file already used them that way, which is why the
   mode switch is a redefinition rather than a rewrite.

   `data-mode` deliberately is NOT `data-theme` — every page sets data-theme
   for Pico, and reusing it would collide.

   Three groups of color, distinguished by whether they invert:
     · role tokens + --wash-rgb  — swap between modes
     · brand FILLS               — identical in both modes (a teal button is
                                   teal on any surface)
     · *-ink steps + --on-*      — the same brand hue re-stepped for legibility
                                   on the current surface, and the pinned text
                                   colors that ride on top of the fills
   Every light-mode step was derived in OKLCH at fixed hue and verified against
   the light surface with the dataviz skill's validate_palette.js — the ratios
   in the comments are measured, not estimated. */
:root {
  --ink: #1c1815;
  --ink-soft: #322b25;
  --paper: #f7f4ee;
  --paper-soft: #d8d2c6; /* labels/titles — keeps the data itself the brightest ink on screen */
  --paper-dim: #b8ac9c;

  /* The "ink on surface" channel behind every wash, hairline and border in this
     file, always written rgba(var(--wash-rgb), α). It is the text color's
     channel, so it lightens the surface in dark mode and darkens it in light. */
  --wash-rgb: 247, 244, 238;

  /* Brand fills — pinned. These are the color the brand *is*, and they read on
     either surface, so a teal button looks the same in both modes. */
  --teal: #5fa2a4;
  --teal-deep: #3c7476;
  --status-critical: #d03b3b;

  /* The same hues re-stepped for text/border/icon use on the current surface.
     In dark mode they are simply the fills; on cream those fills fall to
     2.5–3.8:1 and have to darken. */
  --teal-ink: var(--teal);
  --critical-ink: var(--status-critical);
  --amber: #caa06a;
  --error-text: #e08a7d;

  /* Text that sits ON a brand fill, named for the ink it lays down rather than
     the fill it lands on — both fills legibly take either. Pinned in both modes:
     the fill underneath never changes, so neither may the text on it. Using
     --paper here instead would flip a button's label to brown in light mode
     while its teal plate stayed put. */
  --on-fill-dark: #1c1815; /* 6.04:1 on --teal, 3.67:1 on --status-critical */
  --on-fill-light: #f7f4ee; /* 4.38:1 on --status-critical, 2.66:1 on --teal */

  /* Surfaces layered above the canvas. */
  --surface-raised: #2b251e; /* tooltips, dialogs, picker popovers */

  /* Sticky table heads (.equip-row--head). They sit inside a
     .mem-box, whose background is a TRANSLUCENT rgba(var(--wash-rgb), 0.02)
     over the canvas — but a sticky head has to be opaque or the rows scrolling
     under it show through. So this is the flat, opaque twin of that composite.
     Derived from the canvas rather than hand-set, so it cannot drift the next
     time --ink is changed; the literal above is the fallback for engines
     without color-mix(). The 98%/2% split must stay in step with .mem-box's
     0.02 alpha — change one and you have to change the other. */
  --surface-sticky: #201c19;
  --surface-sticky: color-mix(in srgb, var(--ink) 98%, rgb(var(--wash-rgb)));

  --shadow-soft: 0 4px 14px rgba(0, 0, 0, 0.45);
  --shadow-pop: 0 12px 32px rgba(0, 0, 0, 0.5);
  --shadow-modal: 0 18px 50px rgba(0, 0, 0, 0.55);

  /* Flat chart marks — churn bar, tier bars, status dots — share the brand
     teal so the same two colors mean the same two things everywhere in the
     console. It pairs with --status-critical on the churn bar.

     This is brand teal rather than the higher-chroma --chart-teal step on
     purpose. --chart-teal clears the dataviz chroma floor (0.103 vs 0.10) and
     the 3:1 mark floor on cream (3.06:1) where brand teal does not (0.068 and
     2.66:1) — but every mark using this token carries a text label right beside
     it ("+4", the tier count, ONLINE), which is the secondary encoding those
     thresholds exist to require. Cross-screen consistency was the owner's call
     and is worth more here than a threshold that labels already satisfy.

     --chart-teal itself stays: it is still the hover-brighten step on the teal
     buttons, where nothing is being encoded. */
  --chart-mark-teal: var(--teal);
  --chart-teal: #189ba2;

  /* The growth trend line keeps its own brand teal and same-hue fill, per the
     owner's design direction — deliberately untouched by the above. */
  --chart-growth: #5fa2a4;
  --chart-growth-fill: #cfe2e3;

  /* Shared width for the console's primary action buttons (SAVE, Stripe). */
  --action-btn-width: 176px;

  --pico-primary: var(--teal) !important;
  --pico-primary-background: var(--teal) !important;
  --pico-primary-border: var(--teal) !important;
  --pico-primary-underline: var(--teal-deep) !important;
  --pico-primary-hover: var(--teal-deep) !important;
  --pico-primary-hover-background: var(--teal-deep) !important;
  --pico-primary-hover-border: var(--teal-deep) !important;
  --pico-primary-hover-underline: var(--teal-deep) !important;
  --pico-primary-focus: rgba(95, 162, 164, 0.35) !important;
  --pico-primary-inverse: #fff !important;
}

/* Light mode. Only the tokens that actually change are listed — everything
   pinned above (the brand fills, the on-fill text, the Pico bridge) is
   deliberately inherited unchanged.

   Set only on console.html: the marketing and login pages keep their dark hero,
   whose carousel photography and "everyone in" watermark are composed for a
   dark ground. They never carry the attribute, so they never see this block. */
:root[data-mode="light"] {
  --ink: #eae3d5; /* custom color paper for light mode */
  --ink-soft: #e6e0d5;
  --paper: #1c1815; /* 16.06:1 */
  --paper-soft: #474238; /* 9.09:1 */
  --paper-dim: #6c6152; /* 5.51:1 */
  --wash-rgb: 28, 24, 21;

  --teal-ink: var(--teal-deep); /* 4.84:1 — brand teal itself is only 2.66:1 here */
  --critical-ink: #c32d30; /* 5.12:1 */
  --amber: #8f6732; /* 4.61:1 */
  --error-text: #a9594d; /* 4.53:1 */

  --surface-raised: #fffdf8;
  /* Fallback tracks the current --ink; the color-mix below keeps it exact. */
  --surface-sticky: #e6dfd1;
  --surface-sticky: color-mix(in srgb, var(--ink) 98%, rgb(var(--wash-rgb)));

  /* Black shadows go muddy over cream; same geometry, far less alpha. */
  --shadow-soft: 0 4px 14px rgba(28, 24, 21, 0.14);
  --shadow-pop: 0 12px 32px rgba(28, 24, 21, 0.16);
  --shadow-modal: 0 18px 50px rgba(28, 24, 21, 0.18);

  /* The 2px trend line needs to hold its own against cream; the higher-chroma
     --chart-teal mark step already clears the 3:1 mark floor at 3.06:1. */
  --chart-growth: var(--teal-deep); /* 4.84:1 */
}

body {
  min-height: 100vh;
  /* Avenir for Apple devices; Figtree (loaded from Google Fonts in each page's
     head) is the deliberate Avenir-like fallback everywhere else — without it,
     non-Apple visitors fell to the browser's generic sans-serif and none of the
     letter-spacing tuning below applied to the face it was calibrated for. */
  font-family: "Avenir Next Pro LT", "Avenir Next", Avenir, "Figtree", sans-serif;
}

body.home {
  padding: 0;
}

/* ---- Stage: the two-pane page skeleton (left panel + right pane) ---- */

body.home {
  display: block;
  padding: 0;
}

.stage {
  display: flex;
  min-height: 100vh;
}

.stage:has(.console-canvas) {
  height: 100vh;
  overflow: hidden;
}

.pass-panel {
  position: relative;
  flex: 0 0 clamp(21rem, 32vw, 27rem);
  display: flex;
  align-items: center;
  background: var(--ink);
  color: var(--paper);
  z-index: 2;
  overflow: hidden;
}

.pass-panel::before {
  content: "";
  position: absolute;
  inset: -20% -10% auto -10%;
  height: 60%;
  background: radial-gradient(ellipse at top left, rgba(202, 160, 106, 0.28), transparent 70%);
  pointer-events: none;
}

.pass-panel__inner {
  position: relative;
  width: 100%;
  max-width: 23rem;
  margin: 0 auto;
  padding: 2rem 2.5rem;
}

.pass-panel__inner > * {
  opacity: 1;
}

.pass-logo {
  font-size: 2.75rem;
  line-height: 1;
  color: var(--paper);
  margin-bottom: 1.25rem;
}

@media (prefers-reduced-motion: no-preference) {
  .pass-panel__inner > * {
    opacity: 0;
    animation: pass-fade-up 0.7s ease-out forwards;
  }

  .pass-logo { animation-delay: 0.05s; }
  .pass-eyebrow { animation-delay: 0.15s; }
  .pass-headline { animation-delay: 0.25s; }
  .pass-subhead { animation-delay: 0.35s; }
  .pass-signup { animation-delay: 0.45s; }
  .pass-auth,
  .pass-login-form { animation-delay: 0.55s; }
}

@keyframes pass-fade-up {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* Narrow windows: the side panel becomes the whole page (the right-hand pane —
   marketing carousel or console canvas — is hidden by marketing.css/console.css
   at this same breakpoint). */
@media (max-width: 900px) {
  .stage {
    min-height: 100vh;
  }

  .pass-panel {
    flex: 1 1 auto;
    width: 100%;
  }

  .pass-panel__inner {
    padding: 2.25rem 2rem 2.5rem;
  }
}
