/* =============================================================================
   Raven — palette
   =============================================================================
   THE ONLY FILE IN THE PROJECT PERMITTED TO CONTAIN RAW COLOUR VALUES.
   Every other file references var(--token). A hex, rgb() or hsl() at a use site
   is a violation (frontend-standard §0.2 check 1) — design-lint.sh allow-lists
   this path and nothing else.

   ---------------------------------------------------------------------------
   THE RULE THAT GOVERNS EVERYTHING HERE: COLOUR MEANS SEVERITY OR STATE.
   NOTHING ELSE IS COLOURED.
   ---------------------------------------------------------------------------
   Chrome, navigation and structure are neutral grey, so the moment something is
   coloured it is because it needs attention. The old system spent its entire
   colour system on decoration — every credential tile the same magenta, so a
   root password looked exactly like a note about parking arrangements — and had
   nothing left to signal risk, which is the one thing this interface most needs
   to communicate.

   ONE brand accent, for interactive affordances ONLY — links, focus rings,
   active nav. NEVER for status.

   DARK IS THE PRIMARY TARGET. This is used beside terminals at 2am, and the
   material language depends on deep blacks with real tonal layering above them.
   The light theme is genuinely good, but dark is what the design is FOR.
   ========================================================================== */

/* =============================================================================
   DARK — the default (:root, so it applies with no attribute set)
   ========================================================================== */
:root,
:root[data-theme="dark"] {

  /* ---------------------------------------------------------------------------
     Neutral base — the tonal ladder that produces mass
     ---------------------------------------------------------------------------
     THE GAP BETWEEN --bg AND --surface IS WHAT PRODUCES MASS. Keep it wide
     enough that panels read as objects sitting on a background rather than as
     regions of one. Narrowing it is the single fastest way to make this look
     flat and cheap.
     ------------------------------------------------------------------------ */
  --void:      #08090A;   /* deepest — behind everything */
  --bg:        #0A0B0C;   /* primary page surface */
  --surface:   #17191C;   /* raised panels and rows — clearly ABOVE the bg */
  --surface-2: #1E2226;   /* nested / inset: a card in a card, code blocks,
                             the recessed field a revealed secret sits in */
  --raised:    #23272C;   /* hover, elevated */

  --edge:         #2A2F35;  /* the light-catch along a panel's top edge */
  --border:       #23272C;  /* 1px hairlines — the primary separator */
  --border-strong: #343A41; /* hover / emphasis hairline */

  --ink:   #E6EAED;   /* primary text */
  --ink-2: #A8B0B8;   /* secondary */
  --ink-3: #6B7580;   /* tertiary, labels, muted metadata */

  /* Text on a SATURATED fill is always this, never --ink (§0.2 check 6).
     On a light theme --ink is dark and would be unreadable on an accent fill. */
  --ink-on-strong: #FFFFFF;

  /* ---------------------------------------------------------------------------
     Brand accent — INTERACTIVE AFFORDANCES ONLY. Never status.
     ------------------------------------------------------------------------ */
  --accent:        #4C7DFF;   /* a cold, confident blue */
  --accent-strong: #6B92FF;   /* hover */
  --accent-soft:   #16213D;   /* a tint for a selected row, an active nav item */
  --accent-ring:   #4C7DFFCC; /* focus ring */

  /* ---------------------------------------------------------------------------
     SEVERITY — `sensitivity` maps directly onto colour
     ---------------------------------------------------------------------------
     The single highest-value design decision available. A VM page shows fifteen
     calm grey rows and one red one, and you know which line is dangerous before
     reading a word.

     ORDERING IS FIXED: read_only < user < elevated < admin < root < break_glass.

     NEVER ENCODE MEANING IN COLOUR ALONE. Every severity carries an ICON and a
     TEXT LABEL too — roughly 1 in 12 men has some colour vision deficiency, and
     on a team of a handful that is a real probability rather than a statistic.
     Severity must survive greyscale, and all text clears WCAG AA (4.5:1).

     Note these are SEVERITY tokens, distinct from --warning/--danger. Those two
     are bounded to standalone alert surfaces by §2.3 and may not tint a row, a
     chip or a piece of text. A credential's sensitivity is a permanent property
     of a thing, not an alarm about it — so it gets its own scale.
     ------------------------------------------------------------------------ */
  --sev-read-only: #6B7580;   /* neutral grey — deliberately unremarkable */
  --sev-user:      #7C8792;   /* the majority. Quiet by design. */
  --sev-elevated:  #D9A441;   /* amber — noticeable, not alarming */
  --sev-admin:     #E8833A;   /* orange — administrative */
  --sev-root:      #E5484D;   /* red — visually unmistakable */
  --sev-break-glass: #FF5C7A; /* the one above root. Never covered by a normal
                                 grant, even `root`. */

  /* Dimmed spine variants for a row's resting state; the full value is used on
     hover, focus and for the badge. Keeps fifteen ordinary rows genuinely calm
     so the one red spine is the loudest thing on screen.

     These are DIM, NOT ABSENT. An ordinary credential's spine must still be
     visible against --surface at rest — the design calls for "dim neutral for
     ordinary credentials", and a spine you cannot see is not a spine. Verified
     by eye against --surface (#17191C): each of these clears it distinctly. */
  --sev-read-only-dim: #4E5762;
  --sev-user-dim:      #5A646F;
  --sev-elevated-dim:  #8A6A2C;
  --sev-admin-dim:     #8F5326;
  --sev-root-dim:      #8C2F33;
  --sev-break-glass-dim: #9A3849;

  /* ---------------------------------------------------------------------------
     FRESHNESS / confidence decay (§4.2)
     ---------------------------------------------------------------------------
     The visible answer to "riddled with wrong and outdated information". A small
     dot with a tooltip on every asset, turning staleness from an invisible
     property into a sortable, assignable one.
     ------------------------------------------------------------------------ */
  --fresh-confirmed: #3DA35D;   /* verified, reconciled */
  --fresh-probable:  #7C8792;   /* ageing */
  --fresh-stale:     #D9A441;   /* nobody has verified this in a while */
  --fresh-disputed:  #E5484D;   /* sources contradict each other */

  /* ---------------------------------------------------------------------------
     ALERT COLOURS — standalone alert surfaces ONLY (§2.3, LOCKED)
     ---------------------------------------------------------------------------
     These live ONLY on a component with its OWN box, background, icon and
     structure, sitting ON TOP of the page rather than being a coloured piece OF
     it: .alert, .alert-flag, and destructive affordances (.btn--danger,
     .link--danger).

     NOT a status pill. NOT a tag. NOT a row tint. NOT coloured text. NOT a
     count. (§0.2 check 4 greps for exactly this.)

     Why the bound matters: red and amber ARE plausible accent colours. The
     moment they leak into ordinary themed content, "brand" and "something is
     wrong" become the same colour and the alarm stops meaning anything.
     ------------------------------------------------------------------------ */
  --warning:      #D9A441;
  --warning-soft: #2A2010;
  --danger:       #E5484D;
  --danger-soft:  #2C1315;
  --success:      #3DA35D;
  --success-soft: #10241A;

  /* ---------------------------------------------------------------------------
     Reveal — the most consequential surface in the product
     ---------------------------------------------------------------------------
     The secret sits on a RECESSED inset field that reads as milled into the
     panel, in monospace, with a copy button, a QR button, an auto-clear
     countdown, and a quiet line stating this was logged.
     ------------------------------------------------------------------------ */
  --reveal-well:      #050607;   /* recessed: DARKER than --bg, so it reads as
                                    cut into the surface rather than laid on it */
  --reveal-well-edge: #000000;
  --reveal-text:      #F2F5F7;
  --countdown:        #6B7580;

  /* QR codes are generated LOCALLY — in-browser, never by POSTing plaintext to a
     third-party API. Fixed black-on-white regardless of theme, because scanners
     need real contrast and a generous quiet zone. */
  --qr-fg: #000000;
  --qr-bg: #FFFFFF;

  --backdrop: rgb(4 5 6 / 0.72);
  --shadow-color: 0 0 0;
}

/* =============================================================================
   LIGHT
   =============================================================================
   Genuinely good, not an afterthought — but dark is what the design is for.
   The tonal ladder inverts while keeping the same RELATIONSHIPS: --bg is the
   page, --surface sits above it, --surface-2 is nested/recessed.

   Severity hues shift DARKER here rather than staying identical: the same amber
   that reads clearly on #17191C fails WCAG AA on white.
   ========================================================================== */
:root[data-theme="light"] {
  --void:      #E8EAEC;
  --bg:        #F2F4F6;
  --surface:   #FFFFFF;
  --surface-2: #F2F4F6;
  --raised:    #FFFFFF;

  --edge:          #FFFFFF;
  --border:        #D8DDE2;
  --border-strong: #B9C1C9;

  --ink:   #14171A;
  --ink-2: #4A535C;
  --ink-3: #6B7580;
  --ink-on-strong: #FFFFFF;

  --accent:        #2F5FE0;   /* darkened: #4C7DFF does not clear AA on white */
  --accent-strong: #1F49BF;
  --accent-soft:   #E4EBFC;
  --accent-ring:   #2F5FE0CC;

  --sev-read-only: #6B7580;
  --sev-user:      #5C6670;
  --sev-elevated:  #9A6B10;   /* darkened for contrast on white */
  --sev-admin:     #B4541A;
  --sev-root:      #C22026;
  --sev-break-glass: #A81238;

  --sev-read-only-dim: #C4CBD2;
  --sev-user-dim:      #B8C0C8;
  --sev-elevated-dim:  #E8CE93;
  --sev-admin-dim:     #EDBB9B;
  --sev-root-dim:      #EDA8AA;
  --sev-break-glass-dim: #E79FB2;

  --fresh-confirmed: #1F7A3D;
  --fresh-probable:  #6B7580;
  --fresh-stale:     #9A6B10;
  --fresh-disputed:  #C22026;

  --warning:      #9A6B10;
  --warning-soft: #FDF3DC;
  --danger:       #C22026;
  --danger-soft:  #FCE8E9;
  --success:      #1F7A3D;
  --success-soft: #E3F5E9;

  /* Still recessed, still monospace — a light well reads as inset by being
     DARKER than the panel around it, the same relationship as in dark. */
  --reveal-well:      #E6E9ED;
  --reveal-well-edge: #C9D0D7;
  --reveal-text:      #14171A;
  --countdown:        #6B7580;

  --qr-fg: #000000;
  --qr-bg: #FFFFFF;

  --backdrop: rgb(20 23 26 / 0.42);
  --shadow-color: 20 23 26;
}

/* =============================================================================
   Theme resolution when the user has expressed no preference
   =============================================================================
   Three states, per the standard: an explicit choice stamps data-theme; the
   default "system" setting stamps nothing, so only prefers-color-scheme
   separates light from dark.

   :root already carries the full dark palette above, so a system-light user
   needs the light values applied here — guarded with :not([data-theme]) so an
   explicit dark choice on a light-preferring device still wins.
   ========================================================================== */
@media (prefers-color-scheme: light) {
  :root:not([data-theme]) {
    --void:      #E8EAEC;
    --bg:        #F2F4F6;
    --surface:   #FFFFFF;
    --surface-2: #F2F4F6;
    --raised:    #FFFFFF;

    --edge:          #FFFFFF;
    --border:        #D8DDE2;
    --border-strong: #B9C1C9;

    --ink:   #14171A;
    --ink-2: #4A535C;
    --ink-3: #6B7580;

    --accent:        #2F5FE0;
    --accent-strong: #1F49BF;
    --accent-soft:   #E4EBFC;
    --accent-ring:   #2F5FE0CC;

    --sev-read-only: #6B7580;
    --sev-user:      #5C6670;
    --sev-elevated:  #9A6B10;
    --sev-admin:     #B4541A;
    --sev-root:      #C22026;
    --sev-break-glass: #A81238;

    --sev-read-only-dim: #C4CBD2;
    --sev-user-dim:      #B8C0C8;
    --sev-elevated-dim:  #E8CE93;
    --sev-admin-dim:     #EDBB9B;
    --sev-root-dim:      #EDA8AA;
    --sev-break-glass-dim: #E79FB2;

    --fresh-confirmed: #1F7A3D;
    --fresh-probable:  #6B7580;
    --fresh-stale:     #9A6B10;
    --fresh-disputed:  #C22026;

    --warning:      #9A6B10;
    --warning-soft: #FDF3DC;
    --danger:       #C22026;
    --danger-soft:  #FCE8E9;
    --success:      #1F7A3D;
    --success-soft: #E3F5E9;

    --reveal-well:      #E6E9ED;
    --reveal-well-edge: #C9D0D7;
    --reveal-text:      #14171A;

    --backdrop: rgb(20 23 26 / 0.42);
    --shadow-color: 20 23 26;
  }
}
