/* =========================================================
   Design tokens, fonts, reset and base typography.

   One white ground everywhere. Colour lives in the drawings, the
   keys and the headlines, never in a section's background: the
   footer is the only coloured block on the site.

   The house accents (periwinkle for Skull Solutions, plum for
   SkullSploit, rose for SkullEdu) are kept as families, with four
   more for the floating keys. Each family has the same steps:

     -50 / -100   faint washes (hover grounds, selection)
     -200         object fills inside a drawing
     -300         bright fills: keys, ledged tiles
     -500         the colour itself, and the ledge under a -300
     -700         text on white (every one clears 5:1)
     -900         deepest ink of the family

   The accent never goes on the mascot's face or its ink line.
   ========================================================= */

@font-face {
  font-family: "Fredoka";
  src: url("/fonts/fredoka.27d49d7c.woff2") format("woff2");
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Karla";
  src: url("/fonts/karla.3b1eb09a.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Karla";
  src: url("/fonts/karla-italic.3de0e923.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Mono";
  src: url("/fonts/ibm-plex-mono-400.08949f72.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Mono";
  src: url("/fonts/ibm-plex-mono-500.01d28544.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: light;

  /* ---------- Ink ---------- */
  --ink-900: #17141c;
  --ink-700: #3d3743;
  --ink-500: #5b5563; /* 7.2:1 on white: the grey sentence */
  --ink-300: #a49eaa;
  --ink-100: #ebe8ee;
  --ink-50: #f6f5f7;

  /* ---------- Accent families ---------- */
  --periwinkle-50: #f1f3fc;
  --periwinkle-100: #e2e7f8;
  --periwinkle-200: #ccd4f2;
  --periwinkle-300: #aab8ee;
  --periwinkle-500: #7d8fdc;
  --periwinkle-600: #5562c4; /* the footer: white text at 5.3:1 */
  --periwinkle-700: #4a55a8;
  --periwinkle-900: #262c5a;

  --plum-50: #f8f1f9;
  --plum-100: #f0e2f2;
  --plum-200: #e2c8e6;
  --plum-300: #d3a8da;
  --plum-500: #a873b0;
  --plum-700: #6f4a75;
  --plum-900: #3d2741;

  --rose-50: #fdf2ef;
  --rose-100: #fae3dd;
  --rose-200: #f3c9bf;
  --rose-300: #eea898;
  --rose-500: #d97f6c;
  --rose-700: #9a4a3c;
  --rose-900: #552820;

  --sunbeam-50: #fffaeb;
  --sunbeam-100: #fff1c7;
  --sunbeam-200: #fde49a;
  --sunbeam-300: #fbd35a;
  --sunbeam-500: #e6b021;
  --sunbeam-700: #8a6400;
  --sunbeam-900: #4a3600;

  --aqua-50: #effafb;
  --aqua-100: #d9f3f6;
  --aqua-200: #b5e6ed;
  --aqua-300: #7fd2df;
  --aqua-500: #3aaec2;
  --aqua-700: #1d6f7e;
  --aqua-900: #0f3d45;

  --mint-50: #effaf3;
  --mint-100: #d8f2e1;
  --mint-200: #b4e4c5;
  --mint-300: #85d1a2;
  --mint-500: #4caf74;
  --mint-700: #2e7049;
  --mint-900: #173d27;

  --tangerine-50: #fff5eb;
  --tangerine-100: #ffe6cc;
  --tangerine-200: #ffcf9e;
  --tangerine-300: #ffb36b;
  --tangerine-500: #f28c28;
  --tangerine-700: #a5550c;
  --tangerine-900: #5a2e05;

  /* The accent a component is drawn in. A component sets --accent-name
     classes (.accent-plum, …) and reads these three. */
  --accent-bright: var(--periwinkle-300);
  --accent: var(--periwinkle-500);
  --accent-ink: var(--periwinkle-700);
  --accent-wash: var(--periwinkle-50);

  /* ---------- Grounds ----------
     Every ground is white. The old names stay so the assistant's and the
     estimate builder's styles keep resolving, and all of them say white. */
  --white: #ffffff;
  --paper: var(--white);
  --porcelain: var(--white);
  --ink: var(--ink-900);
  --night: var(--ink-900);
  --night-deep: #12101a;

  /* ---------- Text ---------- */
  --text: var(--ink-900);
  --text-2: var(--ink-700); /* body copy: 11.6:1 on white */
  --text-3: var(--ink-500); /* labels and meta: 7.2:1 on white */
  --on-night: #efe9ef;
  --on-night-2: #bdb4c2;

  /* ---------- Lines ---------- */
  --rule: var(--ink-100);
  --rule-mid: #d9d5dd;
  --rule-strong: var(--ink-900);
  --rule-night: rgb(239 233 239 / 0.16);
  /* A card's edge: light, 2px. Only clickable cards stand on a ledge of it. */
  --edge: #e3e0e7;

  /* ---------- Brand accents (old names, new values) ---------- */
  --sol: var(--periwinkle-500);
  --sol-wash: var(--periwinkle-100);
  --sol-tint: var(--periwinkle-50);
  --sol-ink: var(--periwinkle-700);

  --sploit: var(--plum-300);
  --sploit-ink: var(--plum-700);
  --sploit-deep: var(--plum-700);

  --edu: var(--rose-300);
  --edu-wash: var(--rose-50);
  --edu-ink: var(--rose-700);

  /* ---------- Status ----------
     Always paired with a word (see status() in ui.mjs), never colour alone. */
  --ok: var(--mint-700);
  --warn: var(--sunbeam-700);
  --bad: #b5483d;
  /* The home headline's four verbs: build in green, deploy in orange (the
     rocket key's colour), secure in blue, break in red. Large display text, so each clears 3:1 on white with room. */
  --build: #23874b;
  --deploy: #c9620c;
  --secure: var(--periwinkle-700);
  --break: #d42f24;
  --info: var(--periwinkle-700);

  /* ---------- Type ----------
     Fredoka is the loud half: page titles at 700, sub-headings at 600,
     button labels uppercase. Karla stays underneath it for reading. */
  --font-display: "Fredoka", ui-rounded, "SF Pro Rounded", system-ui, sans-serif;
  --font-body: "Karla", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  --step--2: 0.75rem;
  --step--1: 0.875rem;
  --step-0: 1.0625rem;
  --step-1: clamp(1.125rem, 1.05rem + 0.35vw, 1.3125rem);
  --step-2: clamp(1.375rem, 1.2rem + 0.8vw, 1.75rem);
  --step-3: clamp(1.75rem, 1.4rem + 1.6vw, 2.5rem);
  --step-4: clamp(2.125rem, 1.6rem + 2.6vw, 3.5rem);
  --step-5: clamp(2.5rem, 1.6rem + 4.4vw, 4.75rem);

  /* ---------- Space & layout ---------- */
  --container: 76rem;
  --container-narrow: 52rem;
  --gutter: clamp(1rem, 3.5vw, 2rem);
  --section-space: clamp(3.5rem, 8vw, 6.5rem);
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4.5rem;

  /* Chunky and friendly: keys at 14px, cards at 20px. */
  --radius: 12px;
  --radius-key: 14px;
  --radius-card: 20px;
  --radius-pill: 999px;

  /* The button's offset is printed, not blurred. */
  --offset: 3px 3px 0 var(--ink-900);
  --offset-hover: 5px 5px 0 var(--ink-900);
  --shadow-soft: 0 1px 0 rgb(23 20 28 / 0.04), 0 18px 40px -28px rgb(23 20 28 / 0.35);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  /* Things that overshoot and settle. */
  --ease-spring: cubic-bezier(0.34, 1.36, 0.64, 1);
  --ease-snap: cubic-bezier(0.34, 1.56, 0.64, 1);
  --ease-out-soft: cubic-bezier(0.22, 0.61, 0.36, 1);

  --dur-micro: 0.12s;
  --dur-character: 0.42s;
  --dur-ambient: 4.5s;

  /* ---------- Aliases for chat.css ----------
     The assistant's stylesheet came with the SkullSploit foundation and is
     written against these names. */
  --bg: var(--white);
  --bg-inset: var(--ink-50);
  --fg: var(--ink);
  --muted: var(--text-2);
  --faint: var(--text-3);
  --line: var(--rule-mid);
  --line-soft: var(--rule);
  --line-strong: var(--ink);
  --invert-bg: var(--periwinkle-600);
  --invert-fg: var(--white);
  --accent-tint: var(--sol-tint);
  --step-000: var(--step--2);
  --step-00: var(--step--1);
  --shadow-md: 0 22px 48px -20px rgb(23 20 28 / 0.35);
  --shadow-sm: 0 6px 18px -10px rgb(23 20 28 / 0.25);
  --font-sans: var(--font-body);
  --skull-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath fill='%23000' fill-rule='evenodd' d='M50 8 C24 8 10 26 10 48 C10 64 20 76 32 76 L34 76 L34 83 C34 88 43 88 43 83 L43 76 L45.5 76 L45.5 86 C45.5 91 54.5 91 54.5 86 L54.5 76 L57 76 L57 83 C57 88 66 88 66 83 L66 76 L68 76 C80 76 90 64 90 48 C90 26 76 8 50 8 Z M44.8 45 a10.8 12.4 0 0 1-21.6 0 10.8 12.4 0 0 1 21.6 0 Z M76.8 45 a10.8 12.4 0 0 1-21.6 0 10.8 12.4 0 0 1 21.6 0 Z'/%3E%3C/svg%3E");
}

/* An accent, by name: a component carrying one of these draws its keys,
   its headline and its hover in that family. Assigned from a stable hash of
   a name where the thing has no colour of its own (accentFor() in ui.mjs). */
.accent-periwinkle { --accent-bright: var(--periwinkle-300); --accent: var(--periwinkle-500); --accent-ink: var(--periwinkle-700); --accent-wash: var(--periwinkle-50); --accent-fill: var(--periwinkle-200); }
.accent-plum { --accent-bright: var(--plum-300); --accent: var(--plum-500); --accent-ink: var(--plum-700); --accent-wash: var(--plum-50); --accent-fill: var(--plum-200); }
.accent-rose { --accent-bright: var(--rose-300); --accent: var(--rose-500); --accent-ink: var(--rose-700); --accent-wash: var(--rose-50); --accent-fill: var(--rose-200); }
.accent-sunbeam { --accent-bright: var(--sunbeam-300); --accent: var(--sunbeam-500); --accent-ink: var(--sunbeam-700); --accent-wash: var(--sunbeam-50); --accent-fill: var(--sunbeam-200); }
.accent-aqua { --accent-bright: var(--aqua-300); --accent: var(--aqua-500); --accent-ink: var(--aqua-700); --accent-wash: var(--aqua-50); --accent-fill: var(--aqua-200); }
.accent-mint { --accent-bright: var(--mint-300); --accent: var(--mint-500); --accent-ink: var(--mint-700); --accent-wash: var(--mint-50); --accent-fill: var(--mint-200); }
.accent-tangerine { --accent-bright: var(--tangerine-300); --accent: var(--tangerine-500); --accent-ink: var(--tangerine-700); --accent-wash: var(--tangerine-50); --accent-fill: var(--tangerine-200); }

/* ---------- Reset ---------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

body,
h1,
h2,
h3,
h4,
p,
ul,
ol,
figure,
blockquote {
  margin: 0;
}

ul[role="list"],
ol[role="list"] {
  padding: 0;
  list-style: none;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(5.5rem + env(safe-area-inset-top));
  /* The viewport itself owns the horizontal boundary. Clipping body alone
     can still let overflowing descendants widen the mobile layout viewport.
     Hidden is the fallback for browsers predating clip; pinch zoom stays free. */
  overflow-x: hidden;
  overflow-x: clip;
}

img,
svg {
  display: block;
  max-width: 100%;
}

img {
  height: auto;
}

table {
  border-collapse: collapse;
}

/* ---------- Base ---------- */

body {
  min-height: 100vh;
  background: var(--white);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;
}

h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.01em;
  text-wrap: balance;
  color: var(--ink);
}

h1 {
  font-weight: 700;
}

/* Fredoka has no italic. Emphasis in a headline is the accent instead. */
h1 em,
h2 em,
h3 em {
  font-style: normal;
  color: var(--accent-ink);
}

p {
  text-wrap: pretty;
}

a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
}

a:hover {
  text-decoration-color: var(--accent);
}

strong {
  font-weight: 700;
}

::selection {
  background: var(--periwinkle-200);
  color: var(--ink);
}

/* 3px, and clear of a button's offset. */
:focus-visible {
  outline: 3px solid var(--periwinkle-700);
  outline-offset: 4px;
  border-radius: 6px;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}
