/* Vileda Editor's Handbook — restyled to match the new website UI.
   Tokens taken from Figma "Vileda Playbook + Web V02" › Foundations
   (file jW7B68Zp19QQsYdR0hcvXZ, node 17984:621776), read via the Figma
   connector on 2026-09-25. Content and markup are unchanged — this file
   only maps the handbook's existing classes onto the new tokens.
   Typeface is "TT Norms Pro" in the source file; since that is a
   licensed font and this handbook must keep working fully offline
   (see README), the family below falls back to the closest available
   system sans everywhere it isn't installed.

   Second pass: a handful of chrome elements (search, nav, cards, tags,
   pagination, table header, definition lists) have been redrawn so their
   shapes and colours read as Vileda UI, not generic docs boilerplate —
   the pill tag chips, the rounded card with a coloured edge, the
   accent-bar nav item — while each keeps doing exactly the job it did
   before (filter, navigate, flag yes/no, paginate …). Nothing textual
   changed, only how these elements look. */

:root {
  /* — brand — */
  --brand-red: #d70022;        /* Base/Brand/Primary/60 · Button/Brand bg idle · Status/Error */
  --brand-red-hover: #a90321;  /* Base/Brand/Primary/80 */
  --brand-red-soft: #d700221a;
  --brand-blue: #003184;       /* Base/Brand/Secondary/60 · Link/Primary idle */
  --brand-blue-hover: #002961; /* Base/Brand/Secondary/80 · Link/Primary hover */
  --brand-blue-deep: #031e3e;  /* Base/Brand/Secondary/100 */
  --brand-blue-soft: rgba(0, 49, 132, .08);

  /* — neutrals (Base/Dark scale + semantic Foreground/Background) — */
  --ink: #101012;        /* Foreground/Base/Primary */
  --ink-soft: #555557;   /* Foreground/Base/Secondary */
  --ink-faint: #828285;  /* Foreground/Base/Tertiary */
  --line: #dedee1;       /* Border/Default/Light */
  --line-soft: #eaeaec;  /* Border/Default/Weak */
  --line-strong: #b0b0b3;/* Border/Default/Medium */
  --bg: #ffffff;         /* Background/Base/Primary */
  --bg-alt: #f5f5f8;     /* Background/Base/Secondary */
  --bg-alt2: #eaeaec;    /* Background/Base/Tertiary */

  /* — status — */
  --green: #007a50;
  --green-soft: #007a501a;
  --amber: #f4ad3d;
  --amber-ink: #7a4c06;
  --amber-soft: #f4ad3d1a;
  --red: #d70022;
  --red-soft: #d700221a;

  /* — product-tag palette (Component/Product tag bg, Foundations) —
     Vileda's real site uses these small pill chips on cards to flag
     "new", "low stock" etc.; the handbook borrows the same shapes for
     its own yes/no flags and status notes. */
  --tag-new: #007a50; --tag-new-ink: #ffffff;      /* Novelty */
  --tag-warn: #fa9119; --tag-warn-ink: #402000;     /* Scarcity */
  --tag-info: #003595; --tag-info-ink: #ffffff;     /* Social proof */
  --tag-promo: #feec02; --tag-promo-ink: #3a3300;   /* Promo */

  /* — chapter categories — one accent per content-type group (Page Types,
     Components, Commerce, Base Elements, Technical, Custom Components),
     used for the chapter icons and the overview cards' media area.
     Blue/red are brand tokens; the other hues are documentation-only
     utility colours, chosen to sit quietly next to them rather than
     compete. */
  --cat-page: var(--brand-blue);
  --cat-component: var(--brand-red);
  --cat-commerce: var(--tag-new);
  --cat-base: #6c6c6e;      /* Base/Dark/70 */
  --cat-technical: #b36a00; /* darkened Scarcity, for AA text contrast */
  --cat-custom: #0e7c86;    /* teal, distinct from the Reference field colour */
  --cat-page-soft: rgba(0, 49, 132, .1);
  --cat-component-soft: rgba(215, 0, 34, .1);
  --cat-commerce-soft: rgba(0, 122, 80, .1);
  --cat-base-soft: rgba(108, 108, 110, .12);
  --cat-technical-soft: rgba(179, 106, 0, .12);
  --cat-custom-soft: rgba(14, 124, 134, .1);

  /* — field-type taxonomy (2.3 "Field types you will meet") — a colour
     per family so the Type column reads at a glance, same four families
     the handbook's own text already groups fields into. */
  --type-text: #003184; --type-text-soft: rgba(0, 49, 132, .1);
  --type-ref: #6d3fc0; --type-ref-soft: rgba(109, 63, 192, .1);
  --type-scalar: #555557; --type-scalar-soft: rgba(85, 85, 87, .1);
  --type-app: #b36a00; --type-app-soft: rgba(179, 106, 0, .12);

  /* — chapter icons — one simple, generic glyph per content-type group
     (file / grid / bag / layers / terminal), used as a mask so they pick
     up the --cat colour wherever they appear (h1, chapter <h3>, the
     per-entry id line, the card media placeholder). */
  --icon-page: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/></svg>');
  --icon-component: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg>');
  --icon-commerce: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z"/><path d="M3 6h18"/><path d="M16 10a4 4 0 0 1-8 0"/></svg>');
  --icon-base: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/></svg>');
  --icon-technical: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 17 10 11 4 5"/><line x1="12" y1="19" x2="20" y2="19"/></svg>');
  --icon-custom: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7h3a1 1 0 0 0 1-1V5a2 2 0 0 1 4 0v1a1 1 0 0 0 1 1h3a1 1 0 0 1 1 1v3a1 1 0 0 0 1 1h1a2 2 0 0 1 0 4h-1a1 1 0 0 0-1 1v3a1 1 0 0 1-1 1h-3a1 1 0 0 1-1-1v-1a2 2 0 0 0-4 0v1a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h1a2 2 0 0 0 0-4H5a1 1 0 0 1-1-1V8a1 1 0 0 1 1-1z"/></svg>');

  /* — shape & rhythm (Foundations › Spacing & layout / Corner radius) — */
  --radius: 8px;      /* Corner radius / Radius 8 */
  --radius-lg: 16px;  /* between Radius 8 and Corner radius MD (24) */
  --radius-pill: 999px; /* Corner radius / Full */
  --space-3xs: 4px; --space-xs: 8px; --space-sm: 12px; --space-md: 16px;
  --space-xl: 24px; --space-2xl: 32px;

  --sidebar: 292px;
  --maxw: 1440px;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  --sans: "TT Norms Pro", "TT Norms Pro Variable", -apple-system, BlinkMacSystemFont,
          "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  --shadow-sm: 0 1px 2px rgba(16, 16, 18, .06);
  --shadow-md: 0 8px 24px rgba(16, 16, 18, .08);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --brand-red: #ff6b81;
    --brand-red-hover: #ff8b9c;
    --brand-red-soft: #3a141c;
    --brand-blue: #7da8f2;
    --brand-blue-hover: #a6c4f7;
    --brand-blue-deep: #dbe6fb;
    --brand-blue-soft: rgba(125, 168, 242, .14);

    --ink: #f1f1f3;
    --ink-soft: #b0b0b3;
    --ink-faint: #8c8c90;
    --line: #3e3e40;
    --line-soft: #2a2a2c;
    --line-strong: #555557;
    --bg: #0d0d0f;
    --bg-alt: #17171a;
    --bg-alt2: #202023;

    --green: #4cd6a5;
    --green-soft: #123227;
    --amber: #f4ad3d;
    --amber-ink: #f0c48a;
    --amber-soft: #3a2a14;
    --red: #ff7a8a;
    --red-soft: #3a141c;

    --tag-new: #1f8a63; --tag-new-ink: #eafff4;
    --tag-warn: #c96f10; --tag-warn-ink: #fde9cf;
    --tag-info: #2b5bb0; --tag-info-ink: #eaf1ff;
    --tag-promo: #b8a900; --tag-promo-ink: #fbf7cf;

    --cat-page: #7da8f2;
    --cat-component: #ff6b81;
    --cat-commerce: #4cd6a5;
    --cat-base: #b0b0b3;
    --cat-technical: #e0a552;
    --cat-custom: #4dd7d9;
    --cat-page-soft: rgba(125, 168, 242, .16);
    --cat-component-soft: rgba(255, 107, 129, .16);
    --cat-commerce-soft: rgba(76, 214, 165, .14);
    --cat-base-soft: rgba(176, 176, 179, .14);
    --cat-technical-soft: rgba(224, 165, 82, .16);
    --cat-custom-soft: rgba(77, 215, 217, .16);

    --type-text: #7da8f2; --type-text-soft: rgba(125, 168, 242, .16);
    --type-ref: #b79bf0; --type-ref-soft: rgba(183, 155, 240, .16);
    --type-scalar: #b0b0b3; --type-scalar-soft: rgba(176, 176, 179, .14);
    --type-app: #e0a552; --type-app-soft: rgba(224, 165, 82, .16);

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .3);
    --shadow-md: 0 8px 28px rgba(0, 0, 0, .45);
  }
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; scroll-padding-top: 92px; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 400 16px/1.6 var(--sans);
  letter-spacing: -.006em;
  -webkit-text-size-adjust: 100%;
}

a { color: var(--brand-blue); text-decoration-thickness: 1.5px; }
a:hover { color: var(--brand-blue-hover); }

/* ---------------------------------------------------------- site header */
.topbar {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; gap: 18px;
  padding: 0 24px; height: 72px;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: saturate(180%) blur(10px);
  border-bottom: 1px solid var(--line-soft);
  box-shadow: var(--shadow-sm);
}
.brand { display: flex; align-items: center; gap: 14px; text-decoration: none; color: inherit; }
.brand img { display: block; height: 34px; width: auto; border-radius: 4px; }
.brand .titles { display: flex; flex-direction: column; line-height: 1.25; }
.brand .titles b { font-size: 15.5px; font-weight: 600; letter-spacing: -.01em; }
.brand .titles span { font-size: 12.5px; color: var(--ink-soft); }
.topbar .spacer { flex: 1; }
.topbar .meta {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 12px; font-weight: 500; color: var(--ink-soft); white-space: nowrap;
  padding: 5px 12px 5px 10px; border-radius: var(--radius-pill); background: var(--bg-alt);
}
.topbar .meta::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%; flex: none;
  background: var(--tag-new); box-shadow: 0 0 0 3px var(--green-soft);
}
@media (max-width: 760px) { .topbar .meta { display: none; } .brand .titles span { display: none; } }

/* --------------------------------------------------------------- layout */
.shell { display: flex; align-items: flex-start; max-width: var(--maxw); margin: 0 auto; }

.sidebar {
  position: sticky; top: 72px;
  width: var(--sidebar); flex: 0 0 var(--sidebar);
  height: calc(100vh - 72px); overflow-y: auto;
  padding: var(--space-xl) var(--space-md) 48px;
  border-right: 1px solid var(--line-soft);
}
.sidebar h4 {
  margin: 22px 0 8px; font-size: 11px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-faint);
}
.sidebar h4:first-child { margin-top: 0; }
.sidebar a {
  position: relative; display: block; padding: 7px 12px 7px 16px; margin-left: -12px;
  border-radius: 0 var(--radius-pill) var(--radius-pill) 0; font-size: 14px; font-weight: 500;
  text-decoration: none; color: var(--ink); transition: background-color .12s ease, color .12s ease;
}
.sidebar a::before {
  content: ""; position: absolute; left: 0; top: 50%; translate: 0 -50%;
  width: 3px; height: 0; border-radius: var(--radius-pill); background: var(--brand-red);
  transition: height .14s ease;
}
.sidebar a:hover { background: var(--bg-alt); color: var(--ink); }
.sidebar a.active { background: var(--brand-blue-soft); color: var(--brand-blue); font-weight: 600; }
.sidebar a.active::before { height: 18px; }
.sidebar .sub a { font-size: 13.5px; font-weight: 400; color: var(--ink-soft); padding-left: 16px; }
.sidebar .sub a:hover { color: var(--ink); }
.sidebar .sub a::before { background: var(--brand-blue); }

.content { flex: 1; min-width: 0; padding: 40px 48px 96px; }

@media (max-width: 900px) {
  .shell { display: block; }
  .sidebar {
    position: static; width: auto; height: auto;
    border-right: 0; border-bottom: 1px solid var(--line-soft);
    padding: var(--space-md) var(--space-md);
  }
  .sidebar .sub, .sidebar .subhead { display: none; }
  .content { padding: var(--space-xl) var(--space-md) 64px; }
}

/* --------------------------------------------------------- chapter icons */
/* Each of the five chapter pages sets data-cat on <body>; index.html sets
   it per <h3> instead, since all five chapters live on that one page. */
body[data-cat="page"] { --cat: var(--cat-page); --cat-icon: var(--icon-page); }
body[data-cat="component"] { --cat: var(--cat-component); --cat-icon: var(--icon-component); }
body[data-cat="commerce"] { --cat: var(--cat-commerce); --cat-icon: var(--icon-commerce); }
body[data-cat="base"] { --cat: var(--cat-base); --cat-icon: var(--icon-base); }
body[data-cat="technical"] { --cat: var(--cat-technical); --cat-icon: var(--icon-technical); }
body[data-cat="custom"] { --cat: var(--cat-custom); --cat-icon: var(--icon-custom); }

body[data-cat] h1 { display: flex; align-items: center; gap: 14px; }
body[data-cat] h1::before {
  content: ""; width: 30px; height: 30px; flex: none; background: var(--cat);
  -webkit-mask: var(--cat-icon) center / contain no-repeat; mask: var(--cat-icon) center / contain no-repeat;
}
h3[data-cat] { display: flex; align-items: center; gap: 10px; }
h3[data-cat]::before {
  content: ""; width: 17px; height: 17px; flex: none; background: var(--cat);
  -webkit-mask: var(--cat-icon) center / contain no-repeat; mask: var(--cat-icon) center / contain no-repeat;
}
body[data-cat] .ids::before {
  content: ""; width: 13px; height: 13px; flex: none; background: var(--cat); align-self: center;
  -webkit-mask: var(--cat-icon) center / contain no-repeat; mask: var(--cat-icon) center / contain no-repeat;
}

/* ------------------------------------------------------------ typography */
h1 {
  font-size: 32px; font-weight: 600; line-height: 1.15; margin: 0 0 8px; letter-spacing: -.03em;
}
h2 {
  font-size: 23px; font-weight: 600; margin: 48px 0 12px; padding-top: 20px;
  border-top: 1px solid var(--line-soft); letter-spacing: -.02em;
}
h2:first-of-type { border-top: 0; padding-top: 0; }
h3 { font-size: 18px; font-weight: 600; margin: 32px 0 8px; letter-spacing: -.01em; }
p { margin: 0 0 14px; max-width: 78ch; }
ul { max-width: 78ch; padding-left: 22px; }
li { margin-bottom: 6px; }
code, .mono { font-family: var(--mono); font-size: .88em; }
.lede { font-size: 17.5px; font-weight: 400; color: var(--ink-soft); max-width: 70ch; letter-spacing: -.01em; }
.eyebrow {
  font-size: 12px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase;
  color: var(--brand-red); margin: 0 0 6px;
}

/* ---------------------------------------------------------- model blocks */
.model { scroll-margin-top: 92px; padding-top: 4px; }
.model + .model { margin-top: 56px; border-top: 1px solid var(--line-soft); padding-top: 40px; }
.model h2 { border-top: 0; padding-top: 0; margin-top: 0; }

.ids {
  display: flex; flex-wrap: wrap; gap: 6px 18px;
  font-size: 13px; color: var(--ink-soft); margin: 0 0 10px;
}
.ids b { color: var(--ink); font-weight: 600; }
.ids .mono { color: var(--brand-blue); }

.refs { font-size: 13.5px; margin: 0 0 12px; }
.refs .label { font-weight: 600; color: var(--ink-soft); margin-right: 6px; }
.refs + .refs { margin-top: -6px; }

.status {
  display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase;
  padding: 4px 12px; border-radius: var(--radius-pill);
  background: var(--tag-warn); color: var(--tag-warn-ink); margin-bottom: 12px;
}
.status::before { content: "●"; font-size: 8px; line-height: 1; }

/* ---------------------------------------------------------------- tables */
.tablewrap { overflow-x: auto; margin: 16px 0 0; border: 1px solid var(--line); border-radius: var(--radius); }
table { border-collapse: collapse; width: 100%; font-size: 13.5px; min-width: 860px; }
th {
  text-align: left; font-weight: 600; background: var(--bg-alt);
  padding: 10px 12px; border-bottom: 2px solid var(--brand-blue); white-space: nowrap;
  font-size: 12px; letter-spacing: .03em; text-transform: uppercase; color: var(--ink-soft);
}
td { padding: 10px 12px; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
tr:last-child td { border-bottom: 0; }
td.f-name { font-weight: 600; width: 16%; }
td.f-id { font-family: var(--mono); font-size: 12.5px; color: var(--ink-soft); width: 14%; }
td.f-type { width: 16%; }
td.f-flag { width: 62px; text-align: center; }
td.f-rules { width: 24%; }
td.f-notes { color: var(--ink-soft); }

.flag {
  display: inline-block; min-width: 26px; padding: 1px 9px; border-radius: var(--radius-pill);
  font-size: 11px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase;
  background: var(--bg-alt2); color: var(--ink-soft);
}
.flag.yes { background: var(--tag-new); color: var(--tag-new-ink); }

/* field-type tags — 2.3 groups every field type into four families
   (text, reference, scalar, app); the Type column now shows that
   grouping as colour instead of asking readers to remember the list. */
.type-tag {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12.5px; font-weight: 600; white-space: nowrap;
  padding: 2px 10px 2px 8px; border-radius: var(--radius-pill);
}
.type-tag::before { content: ""; width: 6px; height: 6px; border-radius: 50%; flex: none; background: currentColor; }
.type-tag.type-text { background: var(--type-text-soft); color: var(--type-text); }
.type-tag.type-ref { background: var(--type-ref-soft); color: var(--type-ref); }
.type-tag.type-scalar { background: var(--type-scalar-soft); color: var(--type-scalar); }
.type-tag.type-app { background: var(--type-app-soft); color: var(--type-app); }

/* ----------------------------------------------------------- notes boxes */
.note {
  margin: 18px 0 0; padding: 14px 18px;
  background: var(--amber-soft); border-left: 4px solid var(--amber); border-radius: 0 var(--radius) var(--radius) 0;
}
.note h4 {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 8px; font-size: 13px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--amber-ink);
}
.note h4::before {
  content: "!"; display: grid; place-items: center; flex: none;
  width: 16px; height: 16px; border-radius: 50%; background: var(--amber); color: #ffffff;
  font-size: 11px; font-weight: 800; text-transform: none; letter-spacing: 0;
}
.note ul { margin: 0; padding-left: 20px; }
.note li { font-size: 14px; }

.callout {
  position: relative; margin: 22px 0; padding: var(--space-md) var(--space-xl) var(--space-md) 52px;
  background: var(--bg-alt); border: 1px solid var(--line-soft); border-radius: var(--radius-lg);
}
.callout::before {
  content: "i"; position: absolute; left: 18px; top: 18px;
  width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center;
  background: var(--brand-blue-soft); color: var(--brand-blue); font: 700 13px/1 var(--sans); font-style: italic;
}
.callout h4 { margin: 0 0 8px; font-size: 14px; font-weight: 600; }
.callout p:last-child, .callout ul:last-child { margin-bottom: 0; }

/* --------------------------------------------------------------- figures */
.figures { display: flex; flex-wrap: wrap; gap: var(--space-xl); margin: 22px 0 0; }
figure {
  margin: 0; flex: 0 1 auto; max-width: 100%;
  border: 1px solid var(--line-soft); border-radius: var(--radius); overflow: hidden;
  background: var(--bg-alt);
}
figure img { display: block; max-width: 100%; height: auto; background: #fff; }
figcaption { font-size: 12.5px; color: var(--ink-soft); padding: 8px 12px 10px; max-width: 46ch; }

/* ------------------------------------------------------------ data lists */
.kv { border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; margin: 18px 0; }
.kv div { display: flex; gap: 0; border-bottom: 1px solid var(--line-soft); font-size: 14px; }
.kv div:last-child { border-bottom: 0; }
.kv dt {
  display: flex; align-items: baseline; gap: 8px;
  flex: 0 0 210px; font-weight: 600; padding: 10px 14px; background: var(--bg-alt); margin: 0;
}
.kv dt::before {
  content: ""; width: 6px; height: 6px; flex: none; border-radius: 2px;
  background: var(--brand-blue); translate: 0 -1px;
}
.kv dd { margin: 0; padding: 10px 14px; color: var(--ink-soft); }
@media (max-width: 620px) { .kv div { display: block; } .kv dt { flex: none; } }

/* -------------------------------------------------------------- overview */
/* Content cards: an image where the handbook already has a Playbook
   screenshot for that type, otherwise a chapter icon on a tinted field —
   the same "media area + title + id tag" anatomy as Vileda's real
   Content Card, in place of the plain name/id row this grid used to be. */
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(232px, 1fr)); gap: var(--space-md); margin: var(--space-xl) 0 0; }
.card {
  position: relative; display: flex; flex-direction: column; text-decoration: none; color: inherit;
  overflow: hidden; border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--bg); transition: border-color .12s ease, box-shadow .12s ease, transform .12s ease;
}
.card:hover { border-color: var(--brand-blue); box-shadow: var(--shadow-md); transform: translateY(-2px); }

.card-media {
  position: relative; height: 104px; flex: none; overflow: hidden;
  background: var(--bg-alt2); border-bottom: 3px solid var(--line-strong);
  transition: border-color .16s ease;
}
.card-media img { display: block; width: 100%; height: 100%; object-fit: contain; object-position: center; padding: 6px; box-sizing: border-box; }
.card-media:empty::before {
  content: ""; position: absolute; inset: 0; margin: auto; width: 26px; height: 26px;
  background: var(--ink-faint);
  -webkit-mask: var(--cat-icon, none) center / contain no-repeat; mask: var(--cat-icon, none) center / contain no-repeat;
}
.card:hover .card-media { border-bottom-color: var(--brand-red); }

.card-body { display: block; padding: 14px var(--space-md) var(--space-md); }
.card-body b { display: block; font-size: 15px; font-weight: 600; margin-bottom: 8px; }
.card-id {
  display: inline-block; font-size: 11.5px; color: var(--ink-soft); font-family: var(--mono);
  padding: 2px 8px; border-radius: var(--radius-pill); background: var(--bg-alt2);
}

/* per-chapter colour + icon, set once per grid/section and inherited by
   its cards, its <h3> and (via body[data-cat]) each chapter page's <h1> */
.grid[data-cat="page"], h3[data-cat="page"] { --cat: var(--cat-page); --cat-soft: var(--cat-page-soft); --cat-icon: var(--icon-page); }
.grid[data-cat="component"], h3[data-cat="component"] { --cat: var(--cat-component); --cat-soft: var(--cat-component-soft); --cat-icon: var(--icon-component); }
.grid[data-cat="commerce"], h3[data-cat="commerce"] { --cat: var(--cat-commerce); --cat-soft: var(--cat-commerce-soft); --cat-icon: var(--icon-commerce); }
.grid[data-cat="base"], h3[data-cat="base"] { --cat: var(--cat-base); --cat-soft: var(--cat-base-soft); --cat-icon: var(--icon-base); }
.grid[data-cat="technical"], h3[data-cat="technical"] { --cat: var(--cat-technical); --cat-soft: var(--cat-technical-soft); --cat-icon: var(--icon-technical); }
.grid[data-cat="custom"], h3[data-cat="custom"] { --cat: var(--cat-custom); --cat-soft: var(--cat-custom-soft); --cat-icon: var(--icon-custom); }
.grid .card-media:empty { background: var(--cat-soft); }
.grid .card-media:empty::before { background: var(--cat); }
.grid .card-media { border-bottom-color: var(--cat); }
.grid .card:hover .card-media { border-bottom-color: var(--brand-red); }

.stats { display: flex; flex-wrap: wrap; gap: var(--space-2xl); margin: var(--space-xl) 0 8px; }
.stat b { display: block; font-size: 30px; font-weight: 600; line-height: 1.1; color: var(--brand-red); letter-spacing: -.02em; }
.stat span { font-size: 13px; color: var(--ink-soft); }

/* ---------------------------------------------------------------- search */
.search { position: relative; margin-bottom: 18px; }
.search::before {
  content: ""; position: absolute; left: 16px; top: 13px; width: 15px; height: 15px;
  pointer-events: none; background: var(--ink-faint);
  -webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2.4" stroke-linecap="round"><circle cx="11" cy="11" r="7.5"/><line x1="21" y1="21" x2="16.2" y2="16.2"/></svg>') center / contain no-repeat;
  mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2.4" stroke-linecap="round"><circle cx="11" cy="11" r="7.5"/><line x1="21" y1="21" x2="16.2" y2="16.2"/></svg>') center / contain no-repeat;
}
.search input {
  width: 100%; padding: 11px 14px 11px 40px; font: inherit; font-size: 14px;
  border: 1px solid var(--line); border-radius: var(--radius-pill);
  background: var(--bg); color: var(--ink);
}
.search input:focus { outline: 2px solid var(--brand-blue); outline-offset: -1px; border-color: var(--brand-blue); }
.search input::placeholder { color: var(--ink-faint); }
.search .count { font-size: 12.5px; color: var(--ink-soft); margin-top: 6px; display: block; }
.model.hidden, .card.hidden { display: none; }

/* ---------------------------------------------------------------- footer */
.pagefoot {
  border-top: 1px solid var(--line-soft); margin-top: 64px; padding-top: 20px;
  font-size: 13px; color: var(--ink-soft); display: flex; flex-wrap: wrap; gap: 8px 24px;
}
.prevnext { display: flex; justify-content: space-between; gap: 16px; margin-top: 40px; }
.prevnext a {
  position: relative; flex: 0 1 46%; text-decoration: none; border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill); padding: 12px 20px; color: inherit;
  transition: border-color .12s ease, background-color .12s ease, transform .12s ease;
}
.prevnext a:not(.next) { padding-left: 40px; }
.prevnext a.next { padding-right: 40px; }
.prevnext a:hover { border-color: var(--brand-blue); background: var(--brand-blue-soft); transform: translateY(-1px); }
.prevnext small {
  display: block; color: var(--ink-soft);
  font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
}
.prevnext a:not(.next)::before {
  content: "←"; position: absolute; left: 18px; top: 50%; translate: 0 -50%;
  font-weight: 700; color: var(--brand-blue); transition: translate .12s ease;
}
.prevnext a.next::after {
  content: "→"; position: absolute; right: 18px; top: 50%; translate: 0 -50%;
  font-weight: 700; color: var(--brand-blue); transition: translate .12s ease;
}
.prevnext a:not(.next):hover::before { translate: -3px -50%; }
.prevnext a.next:hover::after { translate: 3px -50%; }
.prevnext .next { text-align: right; margin-left: auto; }

/* ----------------------------------------------------------------- print */
@media print {
  .topbar, .sidebar, .search, .prevnext { display: none !important; }
  .shell, .content { display: block; max-width: none; padding: 0; }
  .model { page-break-inside: avoid; }
  table { min-width: 0; font-size: 9.5pt; }
  a { color: inherit; text-decoration: none; }
  body { font-size: 10.5pt; }
}
