/* ===========================================================================
   tokens.css — the design tokens.

   THIS IS THE ONLY FILE IN THIS REPOSITORY THAT CONTAINS A HEX LITERAL. There
   are none anywhere else in src/ or public/, inline SVG stroke=/fill= attributes
   included, and a new one belongs here rather than where it was needed.

   SINCE SWEB-265 THE SAME IS TRUE OF FONT SIZE. There is no numeric font-size
   left in src/ or public/ — every one of the 122 declarations resolves through
   a step of the type scale below. A new size is a decision about the scale,
   taken here once, not a number typed into the rule that wanted it.

   WHERE THESE VALUES COME FROM, AND WHERE THEY DO NOT.

   They are the ramp the client's CI-Leitfaden publishes (p. 23 of 39, 22.07.2026)
   with the PURPOSE it states for each step — and those stated purposes are where
   the names below come from. They were deliberately NOT read out of the approved
   HTML mockups, which is the one thing that could have gone wrong here: the
   mockups carry three known defects (a hover value that is one digit off the
   locked one, hardcoded strokes of a rejected earlier accent, and a token named
   after a pigment), and extracting from them would have baked all three into the
   token set for every later page to inherit. They stay out — see README, "The
   skin/structure seam".

   LOCKED BY THE CLIENT (`gesperrt`) — not ours to change:
     --color-accent          ramp step 600 — the anchor accent
     --color-accent-hover    ramp step 700 — hover / pressed
   The other eight steps are the system ramp: ours to use, ours to replace.

   TWO RULES, AND THEY ARE THE REASON THIS FILE EXISTS:

   1. A name describes the ROLE, never the pigment. The accent is a warm brown
      today; the client owns the CI and it will move. A token called after the
      colour has to be renamed when the colour changes, which is how a "change it
      in one place" promise turns into a repository-wide search.
   2. Every other file — stylesheet, template, inline SVG — resolves colour
      through var(--*). The test of it is a real one: set the accent to a
      sentinel here, and no brand pixel is left anywhere on the page.

   No preprocessor, no build step: these are native CSS custom properties, and
   what is in this file is what the browser reads.
   =========================================================================== */

:root {
    /* -----------------------------------------------------------------------
       THE ACCENT RAMP — the brand colour, ten steps, one purpose each.
       ----------------------------------------------------------------------- */

    /* 50 — a soft accent background behind a whole area. */
    --color-accent-surface: #FAF4ED;

    /* 100 — badge and highlight fills. */
    --color-accent-badge: #F4E7D8;

    /* 200 — the frame around an accent-tinted area. */
    --color-accent-badge-border: #E8CFB2;

    /* 300 — decorative separation. Sparingly, says the guide. */
    --color-accent-divider: #DBB489;

    /* 400 — the secondary accent. */
    --color-accent-secondary: #CD9A62;

    /* 500 — hover on a light accent surface. */
    --color-accent-surface-hover: #C0864A;

    /* 600 — the accent itself: badge fills, accent surfaces, borders and the
       left-border of an accent-tinted area. NOT buttons and NOT links — since
       SWEB-183 those wear the blue below. LOCKED. */
    --color-accent: #B97A3D;

    /* 700 — hover / pressed on the anchor. LOCKED. */
    --color-accent-hover: #94602F;

    /* 800 — the active accent, and text on an accent tint. */
    --color-accent-active: #6F4823;

    /* 900 — the deepest step of the accent. */
    --color-accent-deep: #4E3218;

    /* A warning eyebrow above a heading — the one line that has to be read
       before the heading it sits on. SWEB-444.

       The value is the client's own: Anna Freudenstein specified #BD8249 by
       number for the Maxibrief post's „Achtung:", calling it Bernstein/Bronze.
       It is NOT a step of the ramp above — it sits between 500 and 600 — so it
       is named for its role rather than filed as a ramp step it is not, which
       is rule 1 at the top of this file. It lives here because rule 2 leaves
       nowhere else for a hex to be.

       ONLY ON A HEADING. It is a step-600-weight value, and the usage rule is
       that 600 and lighter stays on surfaces, borders, buttons and LARGE
       HEADLINES — `.title-eyebrow` is set in the title's own type scale, which
       is what makes it one. Normal-size text takes step 700 or darker. */
    --color-warning-eyebrow: #BD8249;

    /* -----------------------------------------------------------------------
       THE ANCHOR COLOUR — the client's own blue. Headings and product names,
       and since SWEB-183 the site's link and button colour: the navbar's
       navigation links, `Suchen` and `Zurücksetzen` on /kategorien, `Anfrage
       senden` on /anfrageliste, and the homepage call-to-action pair. Body
       links inside running text still resolve through the plain `a` rule in
       components.css and were out of that card's scope.
       ----------------------------------------------------------------------- */
    --color-anchor: #2D4B9B;

    /* Hover / focus on anything wearing the anchor blue — one value for the
       whole site (SWEB-183). A lift off the anchor, not a darkening: the
       hovered control reads as active rather than as pressed. */
    --color-anchor-hover: #4661A7;

    /* A pale wash of the anchor, for illustration fills. From the approved
       mockups, which are the authority for the neutral end of the palette —
       the CI guide publishes the brand and functional colours, not these. */
    --color-anchor-surface: #EEF1F6;

    /* -----------------------------------------------------------------------
       THE CAMPAIGN COLOUR — for a limited-time action, and NOTHING else.
       ----------------------------------------------------------------------- */
    /* Not a second accent and not interchangeable with one. A base component
       may not touch it; only an element explicitly marked as an Aktion may, and
       a gate in tests/design_tokens_test.php enforces exactly that, because the
       one thing that would destroy the distinction is a button quietly reaching
       for the louder colour. */
    --color-action: #F4A51C;

    /* -----------------------------------------------------------------------
       FUNCTIONAL COLOURS — status, never decoration.
       Red is function, the accent is the brand. They are never swapped.

       EXCEPT --color-ok, since 2026-08-08 — Tom ruled the consent banner's
       two buttons (.consent-btn--annehmen / .consent-btn--ablehnen,
       components.css) take this token as their action colour, not a status
       colour: Akzeptieren filled, Ablehnen outlined, both against measured
       3,41 : 1 on white. A named business decision, not an accident — the
       repository-wide contrast check that once measured this was removed
       2026-08-08 at Tom's instruction; this comment records the ruling on
       its own merits, not as an exemption from a check that no longer
       exists.
       ----------------------------------------------------------------------- */
    --color-alert: #C0392B;
    --color-ok: #2E9E5B;

    /* -----------------------------------------------------------------------
       TEXT AND SURFACES — from the approved mockups, verbatim.
       ----------------------------------------------------------------------- */
    --color-text: #1A1A1A;
    --color-text-muted: #555555;
    --color-text-subtle: #888888;

    --color-surface: #FFFFFF;
    --color-surface-raised: #FBFBFC;
    --color-surface-tint: #F7F9FC;
    --color-surface-muted: #F5F5F5;

    --color-border: #E0E0E0;
    --color-border-subtle: #EEEEEE;

    /* -----------------------------------------------------------------------
       TYPE — the CI names Inter, with hierarchy carried by WEIGHT, not colour.
       ----------------------------------------------------------------------- */
    /* SWEB-100. The font FILE is here now, self-hosted under
       public/assets/fonts/ and loaded by the @font-face rules below — never
       fetched from a third-party font CDN, which would send every German
       visitor's IP address to it. The stack still falls back to the system UI
       font first, for the request that arrives before the font file does. */
    --font-sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;

    /* SWEB-342. For the OPERATOR surfaces only — a column heading, an Art.-Nr.,
       a database name, a refusal quoted the way the tool printed it. Nothing a
       visitor sees uses it. It is here rather than in the one stylesheet that
       needs it for the same reason --font-sans is: a font stack written where it
       happens to be needed is the second copy of it that drifts. No font FILE,
       and deliberately so — every candidate below already exists on the machine,
       and shipping a monospace webfont to serve two internal tables would send
       every visitor a file they never render. */
    --font-mono: ui-monospace, "Cascadia Mono", "Segoe UI Mono", "SF Mono", Menlo, Consolas, monospace;

    /* -----------------------------------------------------------------------
       THE TYPE SCALE (SWEB-265) — eight steps, and no other size on the site.

       Colour has lived here since the first commit; size did not. Before this
       card every font-size was a number written where it was needed: 122
       declarations carrying 28 distinct values, seven of them in the right-hand
       column of the product page alone (11 · 12 · 13 · 14 · 15 · 18 · 26). That
       is a size per case, and it is exactly the thing --color-* was created to
       stop happening to the palette.

       THE STEPS ARE NAMED AFTER THEIR ROLE, never after their number or their
       pixels — the same rule the accent ramp above follows and for the same
       reason. A step called --text-14 has to be renamed the day it becomes
       15px, which is how "change it in one place" turns into a search across
       the repository.

       The ladder is a constant ratio of about 1,2 from the floor to --text-
       display. --text-hero is deliberately OFF that ladder, one long stride
       above it: the start page's own claim is the single largest thing on the
       site and it is meant to sit apart. It is used in one place, through
       --text-hero-fluid.

       THE FLOOR IS 11px and nothing on the site goes below it. Three sizes did
       — 9px on the two picture-slot chips, 10px on the image credits and the
       person label, 10,5px on two kickers — and they came up onto the floor.
       ----------------------------------------------------------------------- */

    /* Incidental text: chips, counts, kickers, image credits, article numbers
       in a listing. The smallest type the site is allowed to set. */
    --text-mini: 11px;

    /* Supporting text: breadcrumbs, meta rows, form labels, filter links,
       detail values, footer columns. The most-used step by a wide margin. */
    --text-small: 13px;

    /* Body copy — running text, product names, inputs, buttons and the
       navigation. `body` in base.css is this step and nothing else. */
    --text-body: 16px;

    /* One step above body: lead paragraphs, a heading inside running text,
       the heading of a band. */
    --text-lead: 19px;

    /* Section-level headings, and the largest thing in a card. */
    --text-heading: 23px;

    /* Page-level headings — a product's name, a page's own title. */
    --text-title: 28px;

    /* The top of the ladder. Reached through --text-title-fluid. */
    --text-display: 34px;

    /* Off the ladder on purpose — the start page's claim, one place, reached
       through --text-hero-fluid. */
    --text-hero: 48px;

    /* -----------------------------------------------------------------------
       THE FLUID STEPS — three, and each one runs between two steps of the
       ladder above rather than carrying sizes of its own. That is the whole
       point: a heading that grows with the viewport still lands on the scale
       at both ends, so a narrow window and a wide one are the same system
       rather than two.

       Only a heading that genuinely spans a large range is fluid. Four
       headings that used to clamp across three or four pixels are now a fixed
       step: the mechanism cost more than the range was worth.
       ----------------------------------------------------------------------- */
    --text-heading-fluid: clamp(var(--text-lead), 2.6vw, var(--text-title));
    --text-title-fluid: clamp(var(--text-heading), 3.2vw, var(--text-display));
    --text-hero-fluid: clamp(var(--text-title), 4vw, var(--text-hero));

    /* -----------------------------------------------------------------------
       HOW EACH OLD SIZE WAS PLACED, AND EVERY CASE THAT MOVED.

       The rule was mechanical: each size goes to the NEAREST step, and a size
       exactly between two steps goes to the LARGER one — up, never down, so
       nothing shrinks by accident. 24 of the 122 declarations already sat on a
       step and did not move at all. The rest:

         9px    -> 11px  (+2)     .product-thumb-tag, .category-thumb-tag
         10px   -> 11px  (+1)     .inhalt-bild-marke, .inhalt-platzhalter-marke,
                                  .person-label
         10,5px -> 11px  (+0,5)   .start-kicker, .start-motiv-cap
         11,5px -> 11px  (-0,5)   .product-sku, .product-axes,
                                  .product-variants-sku, .product-image
         12px   -> 13px  (+1)     10 declarations — a tie, resolved upward
         12,5px -> 13px  (+0,5)   8 declarations
         13,5px -> 13px  (-0,5)   13 declarations
         14px   -> 13px  (-1)     12 declarations
         14,5px -> 16px  (+1,5)   12 declarations — a tie, resolved upward
         15px   -> 16px  (+1)     14 declarations
         15,5px -> 16px  (+0,5)   .person-name
         16,5px -> 19px  (+2,5)   .inhalt-text h3 — see the exception below
         17px   -> 16px  (-1)     .start-einstieg-text h3, .start-kontakt-name,
                                  .aktuelles-title
         18px   -> 19px  (+1)     .pd-desc h2
         21px   -> 23px  (+2)     .site-footer-tel
         22px   -> 23px  (+1)     .person-monogramm
         26px   -> 28px  (+2)     .pd-info h1
         30px   -> 28px  (-2)     .start-kennzahl
         0,8125rem -> 13px (0)    .site-footer-note — already 13px, now named

       The eight clamps:

         .start-hero h1       clamp(28,4vw,48)     -> --text-hero-fluid    (identical)
         .pagehead h1         clamp(24,3.2vw,36)   -> --text-title-fluid   (23 … 34)
         .inhalt-hero-claim   clamp(22,3vw,34)     -> --text-title-fluid   (23 … 34)
         .start-kontakt h2    clamp(22,2.8vw,32)   -> --text-title-fluid   (23 … 34)
         .section-title       clamp(20,2.6vw,28)   -> --text-heading-fluid (19 … 28)
         .start-band h2       clamp(18,2.2vw,22)   -> --text-lead          (fixed 19)
         .inhalt-text h2      clamp(18,1.8vw,21)   -> --text-heading       (fixed 23)
         .inhalt-lead         clamp(16,1.6vw,18.5) -> --text-lead          (fixed 19)

       ONE EXCEPTION TO THE NEAREST-STEP RULE, and it is the only one:
       .inhalt-text h3 at 16,5px rounds to --text-body, which is the exact size
       of the .inhalt-text p it heads. A heading inside continuous running text
       is the one place where weight alone is not enough — the reader is
       scanning, not reading, and needs the size cue. It goes up one step to
       --text-lead. Everywhere else a bold label that lands on the same step as
       the copy beside it stays there: it sits at the head of a box or a card,
       and hierarchy carried by WEIGHT is what the CI section above already
       states.
       ----------------------------------------------------------------------- */
}

/* ===========================================================================
   @font-face — Inter, self-hosted (SWEB-100).

   Four static weights, one file each, because that is what the rest of this
   stylesheet and components.css actually set: 400 (body text, the unset
   default), 500, 600 and 700. A variable-font file would cover every weight
   between 100 and 900 for the four this design uses — bytes over the wire for
   a range nothing on the site asks for.

   Each `src` is a same-origin, root-relative path under this project's own
   `public/assets/fonts/` — never a URL to a third-party font service. That is
   the whole reason this ticket exists rather than a one-line comment: a font
   is not a colour or a string the skin-seam gates already watch, so
   tests/font_hosting_test.php is what checks it here instead. This file ships
   to the browser byte for byte, comments included — there is no build step to
   strip them — so this comment deliberately never spells out a competing
   host's name, the same reason head_test.php's vendor host is assembled from
   parts rather than written whole.

   `font-display: swap` — Latin text renders in the fallback stack
   immediately and swaps to Inter when the file arrives, rather than staying
   invisible while it loads.

   The files are the real, static Inter latin subset (SIL Open Font
   License 1.1, upstream github.com/rsms/inter, distributed via the
   @fontsource/inter package) — the Latin-1 Supplement range that subset
   covers is where ä/ö/ü/ß live, so German copy is covered without a second,
   larger latin-ext file.
   =========================================================================== */

@font-face {
    font-family: "Inter";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("/assets/fonts/inter-400.woff2") format("woff2");
}

@font-face {
    font-family: "Inter";
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("/assets/fonts/inter-500.woff2") format("woff2");
}

@font-face {
    font-family: "Inter";
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("/assets/fonts/inter-600.woff2") format("woff2");
}

@font-face {
    font-family: "Inter";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("/assets/fonts/inter-700.woff2") format("woff2");
}
