/**
 * LukeOS Media Hub — Colours & Type
 *
 * A Night Glass-derived system tuned for a photographic media library.
 * Key divergences from Night Glass:
 *   - Flat, SQUARE corners on cards/chrome (2–4px max). Images never round.
 *   - Operator-density chrome — smaller radii, tighter chips.
 *   - Assets render full-bleed in their native aspect ratio; UI never crops
 *     photographs into circles, pills, or heavily rounded cards.
 *
 * Token architecture: palette → roles. Components only ever reference the
 * role tokens (--accent, --bg-*, --fg-*). Palette tokens (--pal-*) are raw
 * values — never referenced by components. To re-theme, change the role
 * map; never hardcode a hex in a component.
 */

/* ===== FONTS ===== */
/* Libre Baskerville — self-hosted (Regular 400 + Bold 700). No local italic
   file was supplied, so italic 400 continues to load from the Google Fonts
   CDN. Drop a LibreBaskerville-Italic.ttf into fonts/ to self-host that too. */
@font-face {
  font-family: 'Libre Baskerville';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/LibreBaskerville-Regular.ttf') format('truetype');
}
@font-face {
  font-family: 'Libre Baskerville';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('https://fonts.gstatic.com/s/librebaskerville/v14/kmKiZrc3Hgbbcjq75U4uslyuy4kn0pNeYRI.woff2') format('woff2');
}
@font-face {
  font-family: 'Libre Baskerville';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/LibreBaskerville-Bold.ttf') format('truetype');
}

/* Baskervville — ANRT revival, self-hosted (weight axis + matching italic).
   Available as an alternate display serif; not wired into a role token yet.
   To adopt it as the heading face, point --font-heading at 'Baskervville'. */
@font-face {
  font-family: 'Baskervville';
  font-style: normal;
  font-weight: 300 900;
  font-display: swap;
  src: url('fonts/Baskervville_wght_.ttf') format('truetype-variations'),
       url('fonts/Baskervville_wght_.ttf') format('truetype');
}
@font-face {
  font-family: 'Baskervville';
  font-style: italic;
  font-weight: 300 900;
  font-display: swap;
  src: url('fonts/Baskervville-Italic_wght_.ttf') format('truetype-variations'),
       url('fonts/Baskervville-Italic_wght_.ttf') format('truetype');
}
/* Rubik — variable weight (300–900), shipped locally. */
@font-face {
  font-family: 'Rubik';
  font-style: normal;
  font-weight: 300 900;
  font-display: swap;
  src: url('fonts/Rubik-VariableFont_wght.ttf') format('truetype-variations'),
       url('fonts/Rubik-VariableFont_wght.ttf') format('truetype');
}
@font-face {
  font-family: 'Rubik';
  font-style: italic;
  font-weight: 300 900;
  font-display: swap;
  src: url('fonts/Rubik-Italic-VariableFont_wght.ttf') format('truetype-variations'),
       url('fonts/Rubik-Italic-VariableFont_wght.ttf') format('truetype');
}

:root {
  /* Token schema version — bump when palette or role map changes
     (also serves as a cache-bust marker for dev servers). */
  --tokens-version: 'quartzite-2';

  /* ===== FONT FAMILIES ===== */
  /* ===== FONT FAMILIES =====
     SCOPE RULE — Baskerville is reserved for asset/record names ONLY.
     The serif is the visual signature for "this is a piece of work":
     image titles, scene names, the identity-block title slot. Anywhere
     else (UI labels, modal titles, role-card headings, system voice,
     buttons, pills) uses --font-body. The serif gains meaning by
     being scarce. Don't use --font-heading on H2/H3 outside of a
     piece-of-work context. */
  --font-heading: 'Libre Baskerville', 'Baskerville', Georgia, 'Times New Roman', serif;
  --font-body:    'Rubik', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono:    ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace;

  /* ======================================================================
     PALETTE — raw colour values. Never referenced by components.
     Components ONLY reference the roles below (--accent, --bg-*, etc.).
     To re-theme, change the role map — not the palette.
     ====================================================================== */

  /* Neutrals — dark (OLED near-blacks + cool greys).
     Named for Tasmanian landscape: obsidian coast, graphite stone,
     alpine quartzite, glacier snow. Hue-neutral by design — previous
     values inherited a blue cast from GitHub's palette; stripped here
     so the chrome reads as rock/graphite, not slate-water. */
  --pal-near-black: #0a0a0c;
  --pal-obsidian:   #070709;
  --pal-ink:        #0e0e10;   /* was #0d1117 (blue-grey) */
  --pal-graphite:   #151518;   /* was #121821 (slate-blue) */
  --pal-slate:      #131316;   /* was #12141a */
  --pal-pewter:     #1c1c20;   /* was #1a1d24 */
  --pal-steel:      #2e2e32;   /* was #30363d */
  --pal-ash:        #484f58;
  --pal-fog:        #6e7681;
  --pal-mist:       #8b949e;
  --pal-quartzite:  #b0b8c0;   /* mid stone-grey — honest to the name */
  --pal-snow:       #f0f3f6;   /* hover-up / selected frame */

  /* Brand — Button Grass Gold. The straw-brown of sun-struck alpine
     button grass plains. Kept in palette as --brand-gold for the LTP
     cameo (sign-in mark, export watermark). Not the UI accent. */
  --pal-buttongrass:       #c9a961;
  --pal-buttongrass-hover: #d9bc7a;
  --pal-buttongrass-light: #e0ca94;
  --pal-buttongrass-deep:  #8a7033;

  /* Gem tones — categorical tagging only */
  --pal-sapphire: #7890b0;
  --pal-emerald:  #6a9585;
  --pal-ember:    #d9a15a;
  --pal-ruby:     #b86a6a;
  --pal-lichen:   #c67154;
  --pal-violet:   #9b85c9;
  --pal-tag-gold: #d4af37;
  --pal-tag-gold-alt: #c9921f;

  /* Functional */
  --pal-success: #5e9b84;          /* muted sage */
  --pal-success-bright: #6fb583;   /* file-safe tick */
  --pal-warning: #c99a5a;           /* dusty amber */
  --pal-error:   #b86a6a;           /* rosewood, not fire engine */

  /* ======================================================================
     ROLES — what components reference. These are the only tokens that
     should appear in preview/kit CSS. Change the right-hand-side to
     re-theme the whole system.
     ====================================================================== */

  /* Backgrounds — near-black for OLED, photographs sit on top with no glow */
  --bg-primary:   var(--pal-near-black);
  --bg-secondary: var(--pal-ink);
  --bg-tertiary:  var(--pal-graphite);
  --bg-card:      var(--pal-slate);
  --bg-elevated:  var(--pal-pewter);
  --bg-hover:     var(--pal-steel);
  --bg-input:     var(--pal-ink);

  /* Page base for hub (layered radial keeps the image gallery feeling
     cinematic — neutralised top stop, no blue cast) */
  --bg-page: radial-gradient(circle at top, #16161a 0%, #0a0a0c 45%, #070709 100%);

  /* Text */
  --fg1: var(--pal-quartzite); /* primary / headings  ~15:1 */
  --fg2: var(--pal-mist);      /* secondary / labels  ~6:1 */
  --fg3: var(--pal-fog);       /* muted / meta        ~4:1 */
  --fg-disabled: var(--pal-ash);
  --fg-invert:   var(--pal-near-black);

  /* Accent — Quartzite. Mid stone-grey of alpine rock.
     Neutral-cool, low-chroma. Zero colour cast next to photographs. */
  --accent:       var(--pal-quartzite);
  --accent-hover: #c5ccd3;
  --accent-light: var(--pal-snow);
  --accent-muted: rgba(176, 184, 192, 0.24);
  --accent-fg:    var(--pal-near-black);   /* text-on-accent */

  /* Brand cameo — Button Grass Gold, the LTP thread. Use ONLY on the
     sign-in mark, export watermarks, and brand certificates. Never on
     UI chrome next to photographs. */
  --brand-gold:       var(--pal-buttongrass);
  --brand-gold-hover: var(--pal-buttongrass-hover);
  --brand-gold-muted: rgba(201, 169, 97, 0.30);

  /* State roles — outcome reporting (toggles, checklists, status pills).
     Distinct from --accent (UI chrome) because state has to *read* as
     state at a glance. Each role pairs with a canonical glyph, defined
     here as a token so swapping the symbol updates every consumer:
        --state-on-glyph   ✓   action taken, outcome good
        --state-wait-glyph ◐   action expected, in motion
        --state-bad-glyph  ✕   action failed or rejected
     Consumers: `content: var(--state-on-glyph)` on a ::before / ::after.
     Dots without colour stay available as ambient categorical markers. */
  --state-on-glyph:   "✓";
  --state-wait-glyph: "◐";
  --state-bad-glyph:  "✕";

  /* Sage bumped slightly brighter so the positive state reads clearly
     without screaming. Still quieter than rosewood (--state-bad) — the
     eye should land on blocked first, positive second. */
  --state-on:        #6db090;                        /* readable sage */
  --state-on-strong: #8ccfa8;                        /* tick on dark */
  --state-on-fg:     var(--pal-near-black);
  --state-on-muted:  rgba(109, 176, 144, 0.22);

  --state-wait:        var(--pal-quartzite);          /* neutral chrome */
  --state-wait-fg:     var(--pal-near-black);
  --state-wait-muted:  rgba(176, 184, 192, 0.18);

  --state-bad:         var(--pal-error);              /* rosewood */
  --state-bad-strong:  #e4a3a3;                       /* cross on dark */
  --state-bad-fg:      #ffffff;
  --state-bad-muted:   rgba(184, 106, 106, 0.18);

  /* Gem tones — categorical tagging (Library filters, workshop pills) */
  --sapphire: var(--pal-sapphire);
  --emerald:  var(--pal-emerald);
  --ember:    var(--pal-ember);
  --ruby:     var(--pal-ruby);
  --lichen:   var(--pal-lichen);
  --violet:   var(--pal-violet);
  --gold:     var(--pal-tag-gold);
  --gold-alt: var(--pal-tag-gold-alt);

  /* Workshop / category colours (picked up by library filters).
     Pastel-band — each named for a Tasmanian/alpine landscape cue so
     filters read as environments, not warning signs. */
  --wk-landscape: #5e8a6e;   /* moss, wet forest floor */
  --wk-astro:     #6b6b8f;   /* dusk violet, blue hour */
  --wk-private:   #8a5a5a;   /* rosewood, reserved */
  --wk-events:    #b37660;   /* terracotta, sun-warmed earth */
  --wk-online:    #6b8aa8;   /* slate blue, distant ridgeline */

  /* Semantic */
  --success:  #10b981;
  --warning:  #f59e0b;
  --error:    #ef4444;
  --info:     var(--sapphire);

  /* File safety / completeness */
  --file-safe:  #3fb950;
  --file-amber: #f59e0b;
  --file-grey:  #6e7681;
  --file-red:   #ef4444;
  --completeness-done:    #3fb950;
  --completeness-partial: #f59e0b;
  --completeness-empty:   #484f58;

  /* Glass (used sparingly for panels; avoid on image overlays) */
  --glass-bg:        rgba(22, 27, 34, 0.85);
  --glass-bg-subtle: rgba(255, 255, 255, 0.03);
  --glass-border:    rgba(255, 255, 255, 0.08);
  --glass-highlight: rgba(255, 255, 255, 0.05);
  --glass-blur:      20px;
  --glass-saturate:  1.1;

  /* Borders */
  --border-subtle: rgba(255, 255, 255, 0.03);
  --border:        rgba(255, 255, 255, 0.06);
  --border-hover:  rgba(255, 255, 255, 0.12);
  --border-strong: #30363d;

  /* Shadows — soft, never heavy; don't fight the photographs */
  --shadow-sm:   0 1px 2px rgba(0, 0, 0, 0.30);
  --shadow-md:   0 4px 6px rgba(0, 0, 0, 0.40);
  --shadow-lg:   0 8px 32px rgba(0, 0, 0, 0.40);
  --shadow-xl:   0 12px 40px rgba(0, 0, 0, 0.50);
  --shadow-soft: 0 4px 16px rgba(0, 0, 0, 0.35);

  /* ===== Radii — square-first =====
     Media Hub diverges from Night Glass here. Photographs are rectangular,
     sharp, unforgiving. UI chrome mirrors the content it frames.
     Images NEVER round. */
  --radius-xs:    2px;   /* inputs, chips, small buttons */
  --radius-sm:    2px;   /* same — operator density */
  --radius-md:    4px;   /* cards (primary) */
  --radius-lg:    6px;   /* elevated cards, modals */
  --radius-badge: 10px;  /* status badges only — deliberate middle ground */
  --radius-full:  9999px;
  --radius-image: 0;     /* PRESENTED photographs are ALWAYS square-cornered
                            (detail hero, gallery tiles, exports). */
  --radius-thumb: 3px;   /* CROP PREVIEWS / chrome-side derivatives.
                            Small radius signals "this is a UI rendering of
                            the photograph", not the finished asset. Use on
                            row thumbs, popover thumbs, picker chips. */

  /* ===== Spacing ===== */
  --space-1: 0.25rem;   /* 4px */
  --space-2: 0.5rem;    /* 8px */
  --space-3: 0.75rem;   /* 12px */
  --space-4: 1rem;      /* 16px */
  --space-5: 1.5rem;    /* 24px */
  --space-6: 2rem;      /* 32px */
  --space-7: 3rem;      /* 48px */
  --space-8: 4rem;      /* 64px */

  /* ===== Transitions ===== */
  --t-fast:   150ms ease;
  --t-normal: 200ms ease;
  --t-slow:   300ms ease;

  /* ===== Type scale ===== */
  --fs-xs:    0.75rem;
  --fs-sm:    0.875rem;
  --fs-md:    1rem;
  --fs-lg:    1.125rem;
  --fs-xl:    clamp(1.25rem, 2vw, 1.5rem);
  --fs-2xl:   clamp(1.5rem, 3vw, 2rem);
  --fs-3xl:   clamp(2rem, 4vw, 3rem);
  --fs-4xl:   clamp(2.5rem, 5vw, 4rem);

  --fw-regular: 400;
  --fw-medium:  500;
  --fw-semi:    600;
  --fw-bold:    700;

  --lh-tight:   1.2;
  --lh-snug:    1.35;
  --lh-normal:  1.6;
  --lh-relaxed: 1.7;

  --tracking-tight:  0.005em;     /* display headings \u2014 open, stately */
  --tracking-normal: 0;
  --tracking-wide:   0.02em;
  --tracking-label:  0.05em;
  --tracking-eyebrow:0.1em;
  --tracking-hero:   0.08em;

  /* Gallery (photograph-specific) */
  --gallery-gap: 4px;
  --gallery-border-color: #ffffff;
  --gallery-border-width: 8px;

  --content-size: 800px;
  --wide-size:    1200px;
}

/* ===== Opt-in theme variants =====================================
   Flip with: <div data-theme="brand-gold"> ... or on <html>.
   Only the auth screen + brand-cameo surfaces should ever use gold.
   ================================================================== */
[data-theme="brand-gold"] {
  --accent:       var(--brand-gold);
  --accent-hover: var(--brand-gold-hover);
  --accent-light: var(--pal-buttongrass-light);
  --accent-muted: var(--brand-gold-muted);
  --accent-fg:    var(--pal-near-black);
}

/* ===== Day Glass (opt-in light theme, rarely used in the hub) ===== */
[data-theme="light"] {
  --bg-primary:   #faf9f6;
  --bg-secondary: #f1efe9;
  --bg-tertiary:  #ebe8e0;
  --bg-card:      #ffffff;
  --bg-elevated:  #f5f3ec;
  --bg-hover:     #e9e6dd;
  --bg-input:     #ffffff;
  --bg-page:      #faf9f6;

  --fg1: #1a1a1a;
  --fg2: #4a4a4a;
  --fg3: #6e7681;
  --fg-disabled: #b5b2ab;
  --fg-invert: #faf9f6;

  /* In light mode Ice would vanish — switch to a deep slate accent */
  --accent:       #1a1a1a;
  --accent-hover: #000000;
  --accent-light: #4a4a4a;
  --accent-muted: rgba(26, 26, 26, 0.18);
  --accent-fg:    #faf9f6;

  --border-subtle: rgba(0, 0, 0, 0.04);
  --border:        rgba(0, 0, 0, 0.08);
  --border-hover:  rgba(0, 0, 0, 0.16);
  --border-strong: #d5d1c6;

  /* State roles — slightly punchier muted backgrounds on cream paper */
  --state-on-muted:   rgba(94, 155, 132, 0.18);
  --state-wait-muted: rgba(110, 118, 129, 0.16);
  --state-bad-muted:  rgba(184, 106, 106, 0.18);
}

/* ===== Semantic element styles ===== */
html { color-scheme: dark; }
[data-theme="light"] { color-scheme: light; }

body {
  background: var(--bg-page);
  color: var(--fg1);
  font-family: var(--font-body);
  font-size: var(--fs-md);
  line-height: var(--lh-normal);
  letter-spacing: var(--tracking-wide);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  margin: 0;
  padding: 0;
}

h1, h2, h3, h4, h5 {
  font-family: var(--font-heading);
  color: var(--fg1);
  font-weight: var(--fw-regular);
  line-height: var(--lh-tight);
  letter-spacing: var(--tracking-wide);
  margin: 0;
}

h1 { font-size: var(--fs-4xl); }
h2 { font-size: var(--fs-3xl); }
h3 { font-size: var(--fs-2xl); }
h4 { font-size: var(--fs-xl); }
h5 { font-size: var(--fs-lg); }

h6, .eyebrow {
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
  color: var(--fg3);
  text-transform: uppercase;
  letter-spacing: var(--tracking-eyebrow);
  margin: 0;
}

p { line-height: var(--lh-relaxed); margin: 0 0 var(--space-4); color: var(--fg1); }
p.lede { font-size: var(--fs-lg); color: var(--fg1); }
p.secondary { color: var(--fg2); }
small, .caption { font-size: var(--fs-sm); color: var(--fg2); }

a {
  color: var(--accent);
  text-decoration: none;
  transition: color var(--t-normal);
}
a:hover { color: var(--accent-hover); }

/* Utility: labels/tabs */
.btn-label, .nav-label {
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  text-transform: uppercase;
  letter-spacing: var(--tracking-label);
}

/* Monospace */
code, pre, .mono {
  font-family: var(--font-mono);
  font-size: 0.85rem;
}
code, pre {
  background: var(--bg-elevated);
  border-radius: var(--radius-xs);
  padding: 0.15em 0.4em;
}

/* Blockquote — serif italic, accent rule */
blockquote {
  font-family: var(--font-heading);
  font-style: italic;
  font-size: var(--fs-xl);
  border-left: 3px solid var(--accent);
  padding: var(--space-2) var(--space-5);
  margin: var(--space-6) 0;
  color: var(--fg1);
}

::selection {
  background: var(--accent);
  color: var(--accent-fg);
}

hr {
  border: 0;
  height: 1px;
  background: var(--border);
  margin: var(--space-6) 0;
}

/* Images: NEVER round. Reusable class. */
.photo, img.photo {
  border-radius: var(--radius-image) !important;
  display: block;
  max-width: 100%;
  height: auto;
}

/* Glass panel utility — used for floating chrome, NOT over images */
.glass-panel {
  background: var(--glass-bg);
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-soft);
}
