/* ============================================================
   Gingham — design tokens
   A calm, clear courseware production environment.
   Cool linen surfaces · soft-blue accents · a quiet check.
   ------------------------------------------------------------
   The brand is named for gingham: a simple, friendly, ordered
   blue check. There is NO weaving / loom / warp-weft metaphor.
   Structure is communicated plainly — clean grids, hairlines,
   and calm validation states. The check is a quiet accent, not
   a concept to lean on.
   ============================================================ */

/* Fresh type pairing — Spectral (display serif), Hanken Grotesk (UI), Spline
   Sans Mono (machinery). SELF-HOSTED via fonts.css + /fonts/*.woff2 (linked from
   index.html), NOT fetched from any font CDN — this keeps the zero-third-party-
   request privacy posture. Do not re-add a remote font @import here. */

:root {
  /* -----------------------------------------------------------
     Brand palette — soft blue accents over bright, neutral linen.
     Eight foundation tokens; chambray carries the brand.
     ----------------------------------------------------------- */
  --linen:         #FBFBFA;   /* bright neutral ivory · primary surface */
  --powder:        #ECEEF0;   /* light neutral-cool · secondary panel, hover */
  --mist:          #D6D8DD;   /* neutral-cool gray · borders, dividers */
  --slate:         #43546E;   /* blue-gray · primary text + icon strokes */
  --chambray:      #3F6CA8;   /* soft blue · active states, primary action, emphasis */
  --fern:          #4F9A52;   /* fresh green · success, healthy validation */
  --honey:         #D9A03A;   /* clean amber-gold · warnings; the blue's complement */

  /* Derived neutrals & shades */
  --linen-deep:    #F0F0ED;   /* darker linen · sit-on-surface hover */
  --linen-light:   #FEFEFD;   /* lightest panel, raised cards */
  --powder-deep:   #DEDFE3;
  --mist-deep:     #B8BAC2;   /* stronger border, hover */
  /* `slate-soft` is text-safe (≈4.9:1 on linen). `slate-faint` is
     large-text / icon-fill only (≈3.6:1). `slate-pale` is
     placeholders / disabled only (≈2:1, never body text). */
  --slate-soft:    #586A86;   /* secondary text */
  --slate-faint:   #7385A2;   /* large-text or icon-fill only */
  --slate-pale:    #A6B3C8;   /* placeholders, disabled — decorative */
  --ink:           #1C2738;   /* near-black cool · headings, dark panels */
  --chambray-soft: #6E92C2;   /* lighter action, hover fills */
  --denim:         #2F5488;   /* deeper blue · pressed, strong emphasis */
  --denim-deep:    #233F66;
  --sky:           #9DB8DC;   /* pale decorative blue · the check, fills only */
  --fern-deep:     #2F6B39;   /* fern text on linen passes AA: 5.9:1 */
  --honey-deep:    #7A5A20;   /* deep amber, large-text / decorative */
  --clay:          #C23B2B;   /* error · a true red-rust, 4.9:1 on linen (AA) */
  --clay-soft:     #D4685A;
  --ember:         #CC2E1B;   /* brighter, more dangerous red — destructive, critical */

  /* Functional aliases — use THESE in components */
  --bg:            var(--linen);
  --bg-raised:     var(--linen-light);
  --bg-panel:      var(--powder);
  --bg-sunken:     var(--linen-deep);
  --rule:          var(--mist);
  --rule-strong:   var(--mist-deep);
  --rule-subtle:   var(--powder);
  --fg:            var(--slate);          /* primary text */
  --fg-strong:     var(--ink);            /* headings */
  --fg-soft:       var(--slate-soft);     /* secondary */
  --fg-faint:      var(--slate-faint);    /* tertiary */
  --fg-pale:       var(--slate-pale);     /* placeholders */
  --accent:        var(--chambray);       /* accent: links, active nav, emphasis */
  --accent-soft:   var(--chambray-soft);
  --accent-deep:   var(--denim);
  --signal-ok:     var(--fern);
  --signal-warn:   var(--honey);
  --signal-err:    var(--clay);
  --signal-info:   var(--chambray);

  /* Color is scarce. The primary action is near-black ink; chambray is
     reserved for accent (links, active state, one emphasis button). */
  --action:        var(--ink);
  --action-hover:  #2A3A52;
  --action-fg:     var(--linen);

  /* Muted pastel fills — soft status backgrounds for chips / badges.
     Kept light so the paired text clears WCAG AA (4.5:1). Decorative;
     always pair with the AA-safe status text colors below. */
  --fill-info:     #E8F0FB;
  --fill-ok:       #E9F2EA;
  --fill-warn:     #FBF4DE;
  --fill-err:      #FBEAE6;
  --fill-neutral:  var(--linen-deep);

  /* AA-safe status TEXT for small labels on the pale fills (and on linen).
     Gold and clay can't clear 4.5:1 as small text on a tint, so warning
     text uses a darker gold and error text uses ember. */
  --text-ok:       var(--fern-deep);         /* 5.5:1 on --fill-ok */
  --text-info:     var(--denim);            /* 6.7:1 on --fill-info */
  --text-warn:     #6E5320;                  /* @kind color */ /* dark amber, 5.6:1 on --fill-warn */
  --text-err:      var(--ember);             /* 4.6:1 on --fill-err */

  /* -----------------------------------------------------------
     Type — editorial serif for meaning, grotesque for work,
     mono for machinery.
     ----------------------------------------------------------- */
  --font-serif:    'Spectral', 'Iowan Old Style', Georgia, 'Times New Roman', serif;
  --font-sans:     'Hanken Grotesk', -apple-system, BlinkMacSystemFont, system-ui, 'Segoe UI', sans-serif;
  --font-mono:     'Spline Sans Mono', ui-monospace, 'SF Mono', 'JetBrains Mono', monospace;

  --font-display:  var(--font-serif);
  --font-body:     var(--font-sans);
  --font-data:     var(--font-mono);

  /* Scale — editorial, modest ratio */
  --t-display-2xl: 72px;   /* marketing hero */
  --t-display-xl:  56px;   /* landing H1 */
  --t-display-lg:  44px;   /* major H1 */
  --t-display-md:  32px;   /* section H2 */
  --t-display-sm:  24px;   /* card title */
  --t-body-lg:     18px;   /* lead paragraph */
  --t-body:        15px;   /* default body — sans, comfortable density */
  --t-body-sm:     14px;   /* dense ui rows */
  --t-caption:     13px;   /* labels, secondary */
  --t-micro:       11px;   /* eyebrows, badges, all-caps */

  --w-light:    300; /* @kind font */
  --w-regular:  400; /* @kind font */
  --w-medium:   500; /* @kind font */
  --w-semibold: 600; /* @kind font */

  /* Line heights */
  --lh-display: 1.06; /* @kind font */
  --lh-heading: 1.18; /* @kind font */
  --lh-body:    1.55; /* @kind font */
  --lh-dense:   1.40; /* @kind font */

  /* Letter spacing */
  --ls-display: -0.022em; /* @kind font */
  --ls-heading: -0.012em; /* @kind font */
  --ls-body:    0em; /* @kind font */
  --ls-micro:    0.11em; /* @kind font */

  /* -----------------------------------------------------------
     Spacing — 4px base
     ----------------------------------------------------------- */
  --s-1:  4px;
  --s-2:  8px;
  --s-3:  12px;
  --s-4:  16px;
  --s-5:  24px;
  --s-6:  32px;
  --s-7:  48px;
  --s-8:  64px;
  --s-9:  96px;
  --s-10: 128px;

  /* -----------------------------------------------------------
     Radii — soft, friendly, not pillowy.
     ----------------------------------------------------------- */
  --r-0:    0px;
  --r-1:    4px;     /* chips, badges */
  --r-2:    6px;     /* default cards, buttons */
  --r-3:    10px;    /* large panels */
  --r-4:    14px;    /* hero containers, app shell */
  --r-pill: 999px;   /* status pills only */

  /* -----------------------------------------------------------
     Shadows — minimalist: near-zero, ultra-diffuse, tinted to the
     slate-blue base. Elevation is communicated by hairlines first.
     ----------------------------------------------------------- */
  --shadow-0: none;
  --shadow-1: 0 1px 0 rgba(28, 39, 56, 0.03);
  --shadow-2: 0 1px 2px -1px rgba(28, 39, 56, 0.06);
  --shadow-3: 0 2px 10px -6px rgba(28, 39, 56, 0.10);
  --shadow-4: 0 16px 40px -22px rgba(28, 39, 56, 0.16);

  /* -----------------------------------------------------------
     Motion — calm and restrained. Nothing snaps or bounces.
     ----------------------------------------------------------- */
  --easing-standard: cubic-bezier(0.2, 0, 0, 1); /* @kind other */
  --easing-emphasis: cubic-bezier(0.3, 0, 0.1, 1); /* @kind other */
  --easing-gentle:   cubic-bezier(0.4, 0, 0.2, 1); /* @kind other */
  --dur-quick: 120ms; /* @kind other */
  --dur-base:  200ms; /* @kind other */
  --dur-slow:  320ms; /* @kind other */
  --dur-settle: 560ms; /* @kind other */  /* validate / repair settle tempo */

  /* -----------------------------------------------------------
     Layout
     ----------------------------------------------------------- */
  --container-narrow: 720px;
  --container:        1100px;
  --container-wide:   1280px;
  --container-full:   1440px;

  /* Gingham check — quiet brand texture. Parameterized so the
     utility classes below can resize / recolor it. */
  --check-size: 16px;            /* one band width */
  /* chambray, as r,g,b for rgba(); overlaps double up */
  --check-ink:  63, 108, 168;    /* @kind color */
  --check-alpha: 0.16;           /* @kind other */
}

/* ============================================================
   Night mode — deep denim. Used sparingly (marketing CTA panel,
   brand applications). NOT the default app surface.
   ============================================================ */
[data-theme="night"],
[data-theme="fabric"] {            /* "fabric" kept as a back-compat alias */
  --bg:          #16223A;   /* deep denim navy */
  --bg-raised:   #1D2C48;
  --bg-panel:    #121C30;
  --bg-sunken:   #0E1626;
  --rule:        #2C3E5E;
  --rule-strong: #41577C;
  --fg:          #C9D5E8;   /* cool light on denim */
  --fg-strong:   #EEF3FA;
  --fg-soft:     #A7B5CD;
  --fg-faint:    #7E8EA8;
  --accent:      var(--sky);
  --check-ink:   157, 184, 220;   /* @kind color */
  --check-alpha: 0.14;            /* @kind other */
}

/* ============================================================
   Element defaults
   ============================================================ */
html, body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-body);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  letter-spacing: var(--ls-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

::selection { background: rgba(63, 108, 168, 0.18); color: var(--fg-strong); }

h1, .h1 {
  font-family: var(--font-display);
  font-size: var(--t-display-xl);
  font-weight: var(--w-regular);
  line-height: var(--lh-display);
  letter-spacing: var(--ls-display);
  color: var(--fg-strong);
  margin: 0;
}

h2, .h2 {
  font-family: var(--font-display);
  font-size: var(--t-display-lg);
  font-weight: var(--w-regular);
  line-height: var(--lh-heading);
  letter-spacing: var(--ls-heading);
  color: var(--fg-strong);
  margin: 0;
}

h3, .h3 {
  font-family: var(--font-display);
  font-size: var(--t-display-md);
  font-weight: var(--w-regular);
  line-height: var(--lh-heading);
  letter-spacing: var(--ls-heading);
  color: var(--fg-strong);
  margin: 0;
}

h4, .h4 {
  font-family: var(--font-body);
  font-size: var(--t-display-sm);
  font-weight: var(--w-semibold);
  line-height: var(--lh-heading);
  letter-spacing: var(--ls-heading);
  color: var(--fg-strong);
  margin: 0;
}

p { margin: 0 0 var(--s-4); text-wrap: pretty; }

p.lead {
  font-family: var(--font-body);
  font-size: var(--t-body-lg);
  color: var(--fg-soft);
  line-height: 1.50;
  max-width: 56ch;
}

small, .caption {
  font-size: var(--t-caption);
  color: var(--fg-soft);
  line-height: var(--lh-dense);
}

.eyebrow {
  font-family: var(--font-sans);
  font-size: var(--t-micro);
  font-weight: var(--w-medium);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--fg-soft);
}

code, pre, kbd, samp, .mono {
  font-family: var(--font-mono);
  font-size: 0.92em;
  line-height: 1.50;
}

pre {
  background: var(--bg-panel);
  border: 1px solid var(--rule-subtle);
  border-radius: var(--r-2);
  padding: var(--s-4);
  overflow: auto;
}

a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-color: rgba(63, 108, 168, 0.32);
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  transition: color var(--dur-quick) var(--easing-standard),
              text-decoration-color var(--dur-quick) var(--easing-standard);
}
a:hover { text-decoration-color: var(--accent); color: var(--denim); }

hr {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: var(--s-6) 0;
}

/* ============================================================
   Gingham check — the one brand texture.
   A soft blue check on a light ground. Two overlapping band
   layers make the classic three tones (ground · band · overlap).
   Use sparingly: a panel backing, an empty state, a hero accent.
   Never wallpaper a whole screen.
   ============================================================ */
.gingham {
  background-color: var(--linen-light);
  background-image:
    repeating-linear-gradient(90deg,
      rgba(var(--check-ink), var(--check-alpha)) 0, rgba(var(--check-ink), var(--check-alpha)) var(--check-size),
      transparent var(--check-size), transparent calc(var(--check-size) * 2)),
    repeating-linear-gradient(0deg,
      rgba(var(--check-ink), var(--check-alpha)) 0, rgba(var(--check-ink), var(--check-alpha)) var(--check-size),
      transparent var(--check-size), transparent calc(var(--check-size) * 2));
}

/* Size variants */
.gingham-fine   { --check-size: 8px; }
.gingham-coarse { --check-size: 24px; }
.gingham-hero   { --check-size: 40px; --check-alpha: 0.13; /* @kind other */ }

/* Tone variants */
.gingham-soft   { --check-alpha: 0.10; /* @kind other */ }                 /* barely-there */
.gingham-sky    { --check-ink: 157, 184, 220; /* @kind color */ }          /* paler blue check */
.gingham-on-panel { background-color: var(--powder); }   /* sit the check on powder */

/* Diagonal cut of the same check — for a hero corner or a band.
   Apply on a positioned, overflow-hidden parent. */
.gingham-band {
  position: relative;
  isolation: isolate;
}
.gingham-band::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(90deg,
      rgba(var(--check-ink), var(--check-alpha)) 0, rgba(var(--check-ink), var(--check-alpha)) var(--check-size),
      transparent var(--check-size), transparent calc(var(--check-size) * 2)),
    repeating-linear-gradient(0deg,
      rgba(var(--check-ink), var(--check-alpha)) 0, rgba(var(--check-ink), var(--check-alpha)) var(--check-size),
      transparent var(--check-size), transparent calc(var(--check-size) * 2));
  -webkit-mask-image: linear-gradient(180deg, #000, transparent);
          mask-image: linear-gradient(180deg, #000, transparent);
}

/* ============================================================
   Fresh-linen surface — an optional, very subtle cool paper
   grain for large surfaces that want a touch of tactility.
   Use on a position: relative element. Keep it barely visible.
   ============================================================ */
.linen-surface { position: relative; }
.linen-surface::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  opacity: 0.10;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='2' stitchTiles='stitch' seed='7'/><feColorMatrix values='0 0 0 0 0.16 0 0 0 0 0.21 0 0 0 0 0.32 0 0 0 1.0 -0.15'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  background-size: 160px 160px;
}

/* Letterpress — a soft inset on display serif over linen, the
   ink-pressed-into-paper feel. Display sizes only, never body. */
.letterpress {
  text-shadow:
    0 1px 0 rgba(255, 255, 255, 0.40),
    0 -1px 0 rgba(28, 39, 56, 0.10);
}

/* ============================================================
   Back-compat aliases.
   The previous system shipped weave / strand / seam / grain
   utilities tied to a loom metaphor we have retired. These
   aliases keep older markup from breaking by mapping it onto
   the calm new system. Prefer the .gingham-* utilities above
   in new work.
   ============================================================ */
.has-grain { position: relative; }
.has-grain::after {
  content: "";
  position: absolute; inset: 0; pointer-events: none; z-index: 1;
  opacity: 0.08; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n2'><feTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='2' stitchTiles='stitch' seed='7'/><feColorMatrix values='0 0 0 0 0.16 0 0 0 0 0.21 0 0 0 0 0.32 0 0 0 1.0 -0.15'/></filter><rect width='100%' height='100%' filter='url(%23n2)'/></svg>");
  background-size: 160px 160px;
}
.has-grain-heavy::after { opacity: 0.12; }

.has-weave, .weave-light, .weave-warp, .weave-twill, .weave-herring,
.weave-coarse, .loom-warp, .weave-fabric {
  background-image:
    repeating-linear-gradient(90deg,
      rgba(63,108,168,0.10) 0, rgba(63,108,168,0.10) 12px,
      transparent 12px, transparent 24px),
    repeating-linear-gradient(0deg,
      rgba(63,108,168,0.10) 0, rgba(63,108,168,0.10) 12px,
      transparent 12px, transparent 24px);
  background-repeat: repeat;
}

/* Seams collapse to a single quiet hairline in the brand blue. */
.seam { display: block; flex-shrink: 0; pointer-events: none; position: relative; }
.seam-thread-v, .seam-double-v, .seam-dashed-v, .seam-knot-v,
.seam-stitched-v, .seam-warp-v {
  width: 1px; align-self: stretch; background: var(--rule); background-image: none; opacity: 1;
}
.seam-thread-h, .seam-double-h, .seam-dashed-h, .seam-knot-h,
.seam-stitched-h, .seam-warp-h, .seam-fringe-h {
  height: 1px; width: 100%; background: var(--rule); background-image: none; opacity: 1;
}

/* Deckle / frayed-corner retired — render as plain edges. */
.has-deckle-top, .has-deckle-bottom { clip-path: none; }
.has-frayed-corner::after { content: none; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}
