/*
 * @file aimeat-atelier.css
 * @author Jouni Miikki
 * SPDX-License-Identifier: MIT
 * @description Stylesheet for the aimeat-atelier SDK library (/v1/libs/aimeat-atelier.js) — the
 *   Atelier track's UI kit: the app shell, hero, KPI row, tabs, bottom navigation, and the
 *   designed empty and loading states.
 *
 *   THIS FILE IS THE THEMING CONTRACT. Every colour, radius, shadow, font, density and motion
 *   value the components read is one of the `--ak-*` custom properties declared below. A look is
 *   authored by setting those properties and NOTHING else — no selector overrides, no component
 *   patches. If a look cannot be reached from these variables, the missing value is a bug in
 *   this contract: add a variable here rather than telling an author to override a class.
 *
 *   VIVID IS THE DEFAULT AND FLAT IS THE CHOICE. The base values below ARE the vivid preset:
 *   a hero band on the brand gradient under a mode-following scrim, tinted cards, a real
 *   entrance. `[data-ak-look='flat']` is the deliberate opt-out that zeroes the decoration.
 *   Every preset colour is a color-mix() expression over the AIMEAT theme tokens — a preset
 *   never introduces a colour of its own, which is what keeps preset × palette × mode
 *   verifiable by arithmetic (pnpm check:atelier, arriving with the preset set).
 *
 *   Each variable falls back to the AIMEAT theme token that means the same thing
 *   (`--color-base-100`, `--color-primary`, `--radius-box`, `--font-body`, …) and, failing
 *   that, to a literal that works on a bare page. So the kit inherits a host that loads
 *   /lib/aimeat-theme.css, and still looks finished on a host that loads nothing.
 *
 *   LIGHT IS THE DEFAULT; `:root[data-theme="dark"]` re-declares the literal fallbacks for dark.
 *   No `rgba(255,255,255,…)` anywhere — light-on-dark washes are `color-mix()` against the
 *   surface token, so they follow the palette instead of fighting it.
 *
 *   THE LIGHT ACCENT HAS A FLOOR UNDER IT. On paper the action ink is white, and a palette is
 *   free to hand this kit an accent too light to carry it, so `--ak-accent` in the light block
 *   is the palette's primary with an OKLCh lightness CAP: chroma and hue untouched, L pulled
 *   down only when the palette sits above the line. AK-SOLID in the matrix is what holds it, on
 *   the RAW accent rather than on the gradient every look already darkens.
 *
 *   MOTION IS FINITE. The entrance tokens drive a one-shot choreography in JS; the only CSS
 *   animations here (skeleton shimmer, loading pulse) carry a finite iteration count, so an
 *   idle Atelier surface repaints zero times and the finish gate can measure that.
 *
 *   A LOOK CARRIES ITS OWN HAND. Speed and curve were always on the contract (--ak-motion,
 *   --ak-ease); the SPRING is too, as --ak-spring-stiffness / --ak-spring-damping /
 *   --ak-spring-mass. The kit's primitives read the three off the element they are moving, so
 *   the same spring() call bounces under carnival and lands flat under editorial without the
 *   app naming a number. They are mode-independent: declared once in the light block, never
 *   re-declared for dark.
 * @structure @import (shell) · the --ak-* token contract (light) · dark re-declaration ·
 *   look presets ([data-ak-look]) · reduced-motion
 * @usage  AIMEAT.atelier.injectStyle() adds it, or link it yourself BEFORE your own styles:
 *   <link rel="stylesheet" href="/lib/aimeat-atelier.css">
 * @version-history
 *   v0.53.2 — 2026-09-13 — No rules changed. The version is pinned to AIMEAT.atelier.version, and
 *     that moved for three script fixes: a section's fill runs with its body in the page, timeline
 *     prints a string that is not a machine date as given, and appRef() works at parse time.
 *   v0.53.1 — 2026-09-05 — No rules changed. The version is pinned to AIMEAT.atelier.version, and
 *     that moved for a script fix: the mosaic's bound figure forwards `unit` and `direction` to
 *     figure(), which it had never done, so a bound figure shows what it is measured in.
 *   v0.53.0 — 2026-09-05 — THE SLIDER IS A KIT FIELD. The form's `type: 'range'` brings its own
 *     row (.ak-form__range with the reading beside the track), its own control skin
 *     (.ak-input--range, the hit area the whole --ak-touch band rather than the 6px rail) and
 *     two per-component tokens, --ak-range-track and --ak-range-thumb, in aimeat-atelier/data.css.
 *   v0.52.0 — 2026-09-05 — WHITE ON CORAL READS ON PAPER (the developer's decision after the
 *     measuring review). The light accent takes an OKLCh lightness CAP —
 *     `oklch(from var(--color-primary, #e8564a) min(l, 0.576) c h)` — so the house coral deepens
 *     from #e8564a to #cf3e35 and white on it goes 3.58:1 → 4.78:1. Hue and chroma are untouched
 *     and a palette already under the cap comes back byte-identical, so crimson, ocean, blue,
 *     forest and magenta do not move and the palette control keeps working. The dark block caps
 *     nothing: its accent ink is near-black. What made this invisible for a month is that the
 *     matrix proved the GRADIENT (AK-GRAD) and every look darkens its gradient stops, while the
 *     tab, the chip, the avatar, the compare handle and the price badge paint the raw accent and
 *     were proven by nothing. AK-SOLID is that missing check, and it fails on the old value in
 *     all nineteen looks. Beside it: a genre body's theme control now says it keeps its own
 *     light instead of doing nothing (see the kit's JS, 0.52.0).
 *   v0.51.0 — 2026-09-05 — NEARLY RIGHT, MADE RIGHT (wish-atelier-always-excellent, part 3).
 *     Thirty-six PER-COMPONENT tokens join the contract — --ak-list-row-gap, --ak-stat-figure-size,
 *     --ak-card-aspect, --ak-hero-title-size and their kind — because the rule of this file was
 *     always "a value a builder would reach for is a variable" and it had only ever held for the
 *     LOOK's values. Every default is the literal the component already carried, so the matrix
 *     and every screenshot are unmoved. custom.css joins the imports and carries the whole
 *     model's own rules, so a builder asking "how do I change this" has one place to look.
 *     Beside them: the parts the components leave EMPTY until
 *     an app fills them (.ak-list__extra, .ak-list__aside, the card's, the timeline's, the
 *     queue's, the kanban's, the hero's kicker/corner, the statRow's unit and direction, the
 *     dialog's four), and the VARIANTS a builder picks instead of overriding
 *     ([data-ak-variant='dense'|'numbered'|'plain'|'tall'|'compact'|'center'|'wide'|'lined'|
 *     'trend'|'pill'|'quiet'] on the component root). --ak-stat-up and --ak-stat-down are the
 *     only new colour names, and both are derived from --ak-ok-text / --ak-err-text, so a look
 *     retunes them with everything else and the matrix proves them where it proved those.
 *   v0.50.0 — 2026-09-05 — MOTION IS THE DEFAULT (wish-atelier-always-excellent, part 2), and the
 *     STILL block now hears all three voices instead of one. The operating system's setting was
 *     the only thing that reached it, so the bar's own Less-motion switch quieted every script in
 *     the kit and left every CSS entrance and shimmer running behind it; `html[data-ak-motion=
 *     "less"]` closes that, and `[data-ak-motion-defaults="off"]` — written by an app's
 *     `motion: false` or a block's — closes the app-side opt-out the same way. No token changes:
 *     the amount of motion was already the look's, in --ak-motion, --ak-ease and the entrance
 *     pair, and a look declaring 0 and 0 still moves nothing.
 *   v0.49.0 — 2026-09-05 — THE MEASURED REVIEW, five findings closed in the kit.
 *     (1) The reduced-motion block reaches ::before and ::after, so the hero's aurora drift —
 *     the one animation in this kit that ran forever under prefers-reduced-motion — stops.
 *     (2) Every compact control reaches 40px of hit area on a phone, off the new --ak-touch-min:
 *     the checkout radio, the carousel and rail dots, the sortable grip, the cart stepper and
 *     remove, the notices mark-all, the facet chip and clear, the search clear, the calendar nav,
 *     the price period, the tour buttons, the poll option, the kanban card, the reading link and
 *     the table sort. A dot keeps its painted mark; only its box grows.
 *     (3) A sideways scroller says so: scroll-edge.js stamps data-ak-scroll="start|middle|end|
 *     none" and the kit paints an edge fade on the side that has more. Every kit scroller gets
 *     it by class; an app opts its own in with data-ak-scroll-edge.
 *     (4) --ak-text-micro (11px) is the one size under the fine floor, and the five places that
 *     wrote 9.8 to 10.9 read it instead.
 *     (5) .ak-facets__sep took a hairline colour as text (1.75 dark, 2.28 light); it is the
 *     muted ink now.
 *   v0.48.0 — 2026-09-05 — THE EFFECTS (wish-atelier-post-process-effects): effects.css joins
 *     the parts — the .ak-fx-* classes effects.js puts on a block, a hero band or a picture,
 *     reading their numbers from the --ak-fx-<id>-<param> properties the kit writes from the
 *     registry's clamp. No token joins the contract: an effect is an arrangement's, not a
 *     look's. The infinite-animation count stays at two; the sheet's one keyframe runs once.
 *   v0.47.1 — 2026-09-05 — content.css: the list-detail fold spans its panes on a phone, and a
 *     tall dialog scrolls inside its body (wish-atelier-listdetail-narrow-fold).
 *   v0.47.0 — 2026-09-05 — THE AMBIENT (wish-atelier-ambient-visuals): three tokens join the
 *     contract — --ak-ambient (a preset id or none), --ak-ambient-alpha and --ak-ambient-speed —
 *     so a LOOK names the one layer allowed to move at idle and the matrix proves it
 *     (AK-AMBIENT). Mode-independent like the spring hand: the layer reads its colours off the
 *     tokens at run time. ambient.css joins the imports: the layer, the aurora drift (the
 *     second and last infinite animation in this kit, beside the hero drift), the stage, the
 *     weather control and attract mode.
 *   v0.46.0 — 2026-09-02 — ROUND THREE: motion-show.css, anime-more.css and lenis-more.css join
 *     the imports (wish-atelier-motion-round-three). Pinned to the JS version, as ever.
 *   v0.45.1 — 2026-09-02 — THE SPRING HAND joins the contract: --ak-spring-stiffness,
 *     --ak-spring-damping and --ak-spring-mass, declared once (mode-independent) and set by
 *     every look, so a feel belongs to the look instead of to whoever wrote the call. The kit's
 *     spring, drag and staggered entrance read them off the element (motion.js).
 *   v0.45.0 — 2026-09-02 — THE SHOW: lenis-director.css (the rail, the pinned scene, the story
 *     well), anime-show.css (the reveal, draw, wave and orbit pieces) and transitions.css (the
 *     curtain layers and the view-transition kinds) join the imports
 *     (wish-atelier-story-director-show). Pinned to the JS version, as ever.
 *   v0.44.0 — 2026-09-02 — MOTION: five sheets join the imports — motion.css (the classes the
 *     drag primitive holds an element under), motion-parts.css (carousel, lightbox),
 *     anime-parts.css (calendar, priceTable), lenis-parts.css (thread, checkout) and
 *     flow-parts.css (sortable, cart, notices, facets) — wish-atelier-motion-libraries-and-
 *     parts. Pinned to the JS version, as ever.
 *   v0.42.0 — 2026-09-01 — NINE PARTS: parts.css joins the imports — the toast stack, the
 *     command palette, the compare slider, the progress ring, the crew stack, the drop zone,
 *     the tour, the poll and the key hints, every value on the contract.
 *   v0.41.0 — 2026-09-01 — MATERIALS AND MOTION: materials.css joins the imports — seven
 *     surfaces (glass, aurora, grain, ink, signal, ring, spot) and six motion recipes (magnet,
 *     tilt, sheen, thumb, odometer, deal), every value a token, nothing looping on idle.
 *   v0.40.0 — 2026-09-01 — BROADCAST, the look (looks.css): the night-gallery world the
 *     developer accepted on the Atelier Next canvas, in light and dark. The channel colours
 *     (--ak-crt-ch1..4) and the set's ground (--ak-crt-set) join the contract here, so a look
 *     may retune the CRT, the countdown and the crawl and the matrix proves it.
 *   v0.39.0 — 2026-08-30 — THE BROADCAST FAMILY: mtv.css joins the imports (the CRT set, the
 *     countdown rows, the news crawl — the Music Television genre's parts as components), and
 *     commercial.css gains the sample chip.
 *   v0.38.0 — 2026-08-30 — THE COMMERCIAL SIDE: commercial.css joins the imports — the legal
 *     pages list and its states, the readiness chip, the legal page frame, the audit trail,
 *     the feedback honeypot, the reviewer line and the marks switches, all on --ak-ok/-warn
 *     and color-mix grounds so every look and mode answers them.
 *   v0.37.0 — 2026-08-30 — Radar rings and shapes + the rating stars (content.css), the steps
 *     tracker (planner.css).
 *   v0.36.0 — 2026-08-30 — THE APPROVED EXPANSION: planner.css joins the imports (kanban,
 *     plan, schedule — the work-planning family's clothes) and content.css learns the funnel,
 *     treemap and flow shapes (label halos via paint-order, so ink reads on any series
 *     colour in both modes).
 *   v0.35.0 — 2026-08-30 — THE APPROVED LEVEL (content.css + data.css): the chart family's
 *     visual language v2 — sheen gradients, per-series fades, the ink tooltip and note bubble,
 *     the donut centre, the calendar ramp, scatter points and trend; the gauge's half-dial;
 *     spark area fills; the model studio's vignette; map touch sizing to the 24px floor.
 *   v0.34.0 — 2026-08-29 — .ak-map (data.css): the real map's chrome on the tokens.
 *   v0.33.0 — 2026-08-29 — The ops family, the atlas and the chart family (data.css): health
 *     lamps, queue states, the gauge dial, the console vane, the offline map, donut and
 *     calendar shapes, KPI trend sparklines. Tones ride --ak-ok/-warn/-err throughout.
 *   v0.32.0 — 2026-08-29 — scene3d: the .ak-scene band (data.css) — real depth on the
 *     three-world bundle, colours from the tokens, render loop parked at rest.
 *   v0.31.0 — 2026-08-29 — THE SCENIC LAYER joins the imports: scenics.css (the genre props)
 *     and patterns.css (gradient-built patterns × three volumes, technique after Temani Afif,
 *     MIT). Born from the thirteen approved genre probes.
 *   v0.30.0 — 2026-08-29 — THE BONES FREED (looks.css): the press-sheet and marquee composition
 *     structures — pages composed like the design canvas posters instead of a band over a pile
 *     of boxes. Riso and stage ride them.
 *   v0.29.0 — 2026-08-29 — WORLDS OWN THEIR GROUNDS: the purity rule is freed into a proof —
 *     a look may carry literal ground pairs (light/dark) that the matrix verifies end to end.
 *     Riso stands on paper, terminal is permanently phosphor-on-black, stage permanently night;
 *     --ak-glass re-declares per look block so the chrome floats on the world's own surface.
 *   v0.28.0 — 2026-08-29 — THE NEXT LEVEL, first landing: --ak-kinetic (masthead letter-throw,
 *     per look), --ak-page-grain (page-wide texture tile: paper for riso, phosphor for terminal),
 *     the chart mural, the cinema choreography, and the riso + stage worlds in looks.css.
 *   v0.27.0 — 2026-08-29 — THE MILK-COFFEE FILM IS GONE. --ak-surface-image painted 4% of the
 *     accent over EVERY card, and five looks repeated it — cards are most of a screen, so that
 *     film was the warm cast the developer kept seeing after the page ground was already cool.
 *     A card separates by its EDGE and its SHADOW now; the page ambient carries the rotated
 *     hues only, never the accent itself. Also: `hidden` finally hides — every kit surface sets
 *     a display, which beat the attribute, so an app that hid a section watched it stay.
 *   v0.26.0 — 2026-08-29 — THE LANE AND THE BAND, both rules the developer never chose:
 *     --ak-main-max goes 68rem → 100% (room by default; the reading looks keep their measure
 *     and the main column gains growing side air), and --ak-hero-min goes 30dvh → 11rem, so a
 *     band is sized by what stands in it instead of by a slice of the window. A page that
 *     wants a lane back says so in one token.
 *   v0.25.0 — 2026-08-29 — The things that open, styled (content.css: the dialog department,
 *     the drawer, the reveal fan) and the DANGER button (shell.css) — outlined, its ink built
 *     the way --ak-accent-text is, so the destructive answer is readable by the same
 *     arithmetic in every palette.
 *   v0.24.0 — 2026-08-29 — The looks gain their CURVES (looks.css): sticker, carnival and
 *     billboard ride a springy overshoot, so a motion recipe is a hand and not just a speed.
 *   v0.23.0 — 2026-08-28 — BILLBOARD joins the looks (looks.css): the whole screen is the
 *     poster — no measure column, a half-viewport banner, carnival's printed depth at room
 *     scale. Matrix 4285/4285 over 14 looks × 12 palette-modes (Voltage included).
 *   v0.22.0 — 2026-08-28 — THE VOLUME RULE FREED (the developer's direction): the tilt is a
 *     hover greeting, never a resting posture (cards and tiles stand straight; the look's tilt
 *     fires on hover/focus/current, with a lift); the monogram grounds commit to real chroma
 *     off the spectrum (the imagery slot was never bound by the surface-tint budget — pastel
 *     there was timidity, not a rule) and the letter wears the brand gradient cut into the
 *     glyph; the vivid aurora deepens (36/34/32 within the mesh cap). The readability floors
 *     did not move: matrix 3292/3292.
 *   v0.21.0 — 2026-08-28 — The nesting guard (looks.css): every look block declares the
 *     inverse-band trio — own value or contract default — so a nested look never inherits the
 *     outer look's band type.
 *   v0.20.0 — 2026-08-28 — The harvest trio's styles (content.css): the matrix grid, the graph
 *     pills and edges, the waveform bars.
 *   v0.19.0 — 2026-08-28 — The chart's styles (content.css: bars, drawn lines, mono ticks, the
 *     worded legend) — the harvest's first component.
 *   v0.18.0 — 2026-08-28 — The INVERSE BAND joins the contract: --ak-hero-ink / --ak-hero-ink-dim
 *     name the hero's own text pair (default: the page ink; the subline no longer dims by
 *     default — it measured 3.2:1 on the band's real grounds), and the carnival look arrives —
 *     the front-demo2 register: a saturated three-hue banner with light type on a thin dark
 *     scrim, thick ink borders, hard offset shadows, sticker tilt. All proven: the matrix now
 *     models the band's true grounds (the brand gradient under the mesh, never the bare page)
 *     and checks the declared hero pair — 3292 checks over 13 looks.
 *   v0.17.0 — 2026-08-28 — The signature colour pair ships (no stylesheet change: the mosaic
 *     injects the per-mode `--ak-accent` scoped to its host; every accent derivation below
 *     follows the pair through var()).
 *   v0.16.0 — 2026-08-28 — The delegate handle's row styles (content.css) beside the phase-6
 *     agentness pair (delegate + agentActivity in the kit).
 *   v0.15.0 — 2026-08-28 — The boot gate (shell.css: .ak-app--gate centers the status card and
 *     hides the empty main; .ak-body clips overflow so no second scrollbar ever appears).
 *   v0.14.0 — 2026-08-28 — copilot → aide: the panel classes are .ak-aide__* now. Renamed before
 *     any app used the block, so nothing breaks; the developer picked the name.
 *   v0.13.0 — 2026-08-28 — The AI-native layer (content.css: the copilot panel — log, bubbles,
 *     confirm row, inline generated panel — and the explain list).
 *   v0.12.0 — 2026-08-28 — The signature and the morphs (JS side: mosaic tokens + shared-element
 *     view transitions). No stylesheet change beyond this pin line — the version moves with the
 *     kit it is pinned to.
 *   v0.11.0 — 2026-08-28 — The first AEB review's seven kit fixes (shell.css + content.css +
 *     shell/hero/list/i18n JS): a designed sign-in state after the boot grace instead of an
 *     endless "Loading…", the bar heading yielding when a hero carries the same name, the bar
 *     wrapping so the pill cannot crush the title at 390px, short-viewport caps extended, the
 *     empty state slimmed, the featured card's wide-band cover with a chip monogram, and a
 *     visible selected row + detail brought into view on pick.
 *   v0.10.0 — 2026-08-27 — Scroll reveals (mosaic.css: units rise into view on the composition
 *     grid, distance from the look's entrance token, flat opts out) and the overlay menu — one
 *     Menu control opening a full-screen list in display type over an accent-breathed, blurred
 *     ground, numbered in mono, Escape to close.
 *   v0.9.0 — 2026-08-27 — The figure: the data IS the hero (shell.css part) — one giant
 *     accent-inked display numeral with a mono small-caps label, the Cape Town move from the
 *     research base, reachable as the mosaic `figure` component.
 *   v0.8.0 — 2026-08-27 — THE LOOK FACTORY: every preset block moves to the GENERATED
 *     ./aimeat-atelier/looks.css, emitted from the one registry (src/data/atelier-looks.ts)
 *     that also drives the build prompt's look table and the mosaic catalogue's look sheets.
 *     Structure recipes (masthead, joined, full-bleed-hero) become shared vocabulary any look
 *     declares. Five new looks arrive as data entries — broadsheet, gallery, brutalist,
 *     terminal, aurora — and the matrix (now 120 combinations) proves each automatically.
 *     check:atelier refuses drift between the registry and the emitted file.
 *   v0.7.0 — 2026-08-27 — COMPOSITION, on the developer's award-site references: the missing
 *     axis was layout, not colour. The mosaic gains a six-column composition grid (per-block
 *     span: full/main/side/half), the `rail` navigation (a desktop-grade left rail folding to a
 *     strip on phones), editorial becomes a real front page (masthead hero on rules, giant
 *     joined numerals, cells sharing hairlines in one frame), poster's band runs edge to edge,
 *     and the measure cap rises from the 52rem tube to 68rem (editorial 76, neon 80).
 *   v0.6.0 — 2026-08-27 — THE SPECTRUM RELEASE, on the developer's "irrottele" directive. Two
 *     hues derived from the accent by OKLCh rotation (lightness never moves, so every proven
 *     contrast holds) turn the hero mesh into an aurora and the brand gradient two-hued; the
 *     page ground carries a whisper-quiet ambient of the same spectrum; dark surfaces lean
 *     toward the accent instead of neutral grey and raised things faintly glow; the bar and the
 *     bottom nav float on saturated glass; film grain rides an inline colourless SVG; and the
 *     hero's aurora DRIFTS — a 46s compositor tween behind a scrim that stays put, mutating no
 *     DOM and collapsing under reduced motion. Flat, calm-card and editorial opt out of what
 *     contradicts them. Verified: AK-PAGE (ink on every ambient stop + the whisper cap) and
 *     AK-GLASS (bar ink on the composited pane) join the matrix.
 *   v0.5.0 — 2026-08-27 — The energetic presets commit: poster's hero ground IS the brand
 *     gradient (48dvh, 900-weight display up to 5.2rem, extruded), sticker tilts the whole grid
 *     (±2°, chunky offset shadows, 24px pills), neon-dense gets its accent ring + glow and an
 *     accent-tinted hairline. Card tilt reaches .ak-grid (zero everywhere but sticker).
 *   v0.4.1 — 2026-08-27 — The stylesheet imports its own token upstream (aimeat-theme.css):
 *     palette accents, real webfonts and each palette's display personality now reach every
 *     Atelier app through the one link the shell already has. Found in a real browser: the login
 *     pill's palette control did nothing, because the --ak-* chains fell through to their
 *     literal fallbacks with no theme tokens on the page.
 *   v0.4.0 — 2026-08-27 — The mosaic part arrives (mosaic.css): the five navigation projections
 *     of one stored layout — stacked units, the tabs/bottom-bar picker, the scroll-snap deck
 *     with dots, the flow stepper, and the pan-zoom canvas whose tiles expand to full view.
 *     Motion on input only; the deck and the canvas own their overflow.
 *   v0.3.4 — 2026-08-27 — Every .ak-root is a positioning context: an unanchored screen-reader
 *     span escaped to the document and stretched the page past its own frame.
 *   v0.3.3 — 2026-08-27 — The main scroller's children never flex-shrink: the tab row (a flex
 *     child with its own overflow) was crushed to 12px once content exceeded the scroller.
 *   v0.3.2 — 2026-08-27 — .ak-body (margin 0 + page ground) for the full-frame app: the browser's
 *     default body margin left an 8px gutter around the frame. Found by the real-browser run.
 *   v0.3.1 — 2026-08-27 — Kit release marker only (the JS↔CSS version pin): the shell's boot
 *     defers one tick so onReady never fires before app() returns. No stylesheet rule changed.
 *   v0.3.0 — 2026-08-27 — The content and data parts arrive (content.css: keyed list,
 *     master–detail with a container-query split, card grid with deterministic monogram
 *     washes, timeline; data.css: the declared form, the table that scrolls in its own box,
 *     the search bar), plus .ak-badge and .ak-sr-only in the shared primitives.
 *   v0.2.0 — 2026-08-27 — The full preset set: calm-card, editorial, sticker, neon-dense and
 *     poster join vivid and flat, every block tagged @preset-block for pnpm check:atelier (the
 *     70-combination arithmetic matrix, TARGET-074's growth rule). Display-treatment tokens
 *     arrive in the contract: --ak-display-shadow, --ak-display-stroke, --ak-tilt.
 *   v0.1.0 — 2026-08-27 — Initial slice: the --ak-* token contract (surfaces, colour, shape,
 *     type, motion, chrome reserve), vivid-as-default values, the flat preset, dark
 *     re-declaration, and the shell part (TARGET-074 phase 1, slice 1).
 */

/* The token UPSTREAM: the platform theme (palette accents, light/dark grounds, the self-hosted
 * faces — Inter, Space Grotesk, Fraunces, JetBrains Mono — and each palette's display
 * personality). Every --ak-* value chains to these; without them the literal fallbacks win and
 * the login pill's palette control does nothing. The kit owns its composition: one link. */
@import url('./aimeat-theme.css');

@import url('./aimeat-atelier/shell.css');
@import url('./aimeat-atelier/content.css');
@import url('./aimeat-atelier/data.css');
@import url('./aimeat-atelier/planner.css');
/* The customisation model's own sheet: the parts every component leaves EMPTY until an app fills
 * them, and the variants a builder picks. It follows the four sheets above so a variant rule
 * always lands after the rule it narrows. */
@import url('./aimeat-atelier/custom.css');
@import url('./aimeat-atelier/commercial.css');
@import url('./aimeat-atelier/mtv.css');
@import url('./aimeat-atelier/materials.css');
@import url('./aimeat-atelier/parts.css');
@import url('./aimeat-atelier/motion.css');
@import url('./aimeat-atelier/motion-parts.css');
@import url('./aimeat-atelier/anime-parts.css');
@import url('./aimeat-atelier/lenis-parts.css');
@import url('./aimeat-atelier/flow-parts.css');
@import url('./aimeat-atelier/lenis-director.css');
@import url('./aimeat-atelier/lenis-more.css');
@import url('./aimeat-atelier/anime-show.css');
@import url('./aimeat-atelier/anime-more.css');
@import url('./aimeat-atelier/motion-show.css');
@import url('./aimeat-atelier/transitions.css');
@import url('./aimeat-atelier/scenics.css');
@import url('./aimeat-atelier/patterns.css');
@import url('./aimeat-atelier/mosaic.css');
@import url('./aimeat-atelier/ambient.css');
@import url('./aimeat-atelier/effects.css');
/* LAST on purpose: the generated look blocks (tokens + structure recipes) override the parts. */
@import url('./aimeat-atelier/looks.css');

/* ══════════════════════════════════════════════════════════════════════════════════════════
   THE CONTRACT — light. Set these to author a look; do not override component selectors.
   The base values ARE the vivid preset.
   ══════════════════════════════════════════════════════════════════════════════════════════ */
/* @preset-block vivid */
:root {
  /* ── Surfaces and ink ─────────────────────────────────────────────────────────────────── */
  --ak-bg:            var(--color-base-100, #f3f5f8);   /* the page                          */
  --ak-surface:       var(--color-base-200, #ffffff);   /* cards, bars, panels               */
  --ak-surface-2:     var(--color-base-100, #eceff4);   /* rows nested inside a surface      */
  /* Vivid: a card is tinted toward the brand, never flat. Flat zeroes this. 4% is the
     check:atelier ceiling in practice: at 5% the mist palette's tinted card no longer
     stepped off the page. */
  --ak-surface-image: none;
  --ak-ink:           var(--color-base-content, #151a21);
  /* 68%: the check:atelier floor — at 62% the mist palette's dimmed text fell to 4.37:1. */
  --ak-ink-dim:       color-mix(in oklab, var(--ak-ink) 68%, var(--ak-surface));
  --ak-line:          var(--color-base-300, #d7dce4);   /* hairlines, card edges             */
  --ak-line-w:        var(--border-w, 1px);

  /* ── Meaningful colour ────────────────────────────────────────────────────────────────── */
  /* THE LIGHT ACCENT CARRIES A READABILITY FLOOR (2026-09-05, the developer's decision after the
   * measuring review). White is the action ink on paper, and the house coral #e8564a measured
   * 3.58:1 under it — on the tab, the chip, the avatar, the compare handle, the price badge and
   * five more, every one of them painting `background: var(--ak-accent)` raw. The gradient was
   * never the problem: every look already darkens --ak-grad toward the ink, which is why the
   * primary action read and the flat fills did not.
   * The cap is an OKLCh lightness ceiling, not a new colour: chroma and hue are untouched, L is
   * pulled down only when the palette sits above the line, and a palette already under it comes
   * back byte-identical (crimson, ocean, blue, forest and magenta do not move). So the login
   * pill's palette control keeps working and the coral keeps its character — it deepens from
   * #e8564a to #cf3e35, 4.78:1 with white. 0.576 is the L of the nearest shade that clears 4.5
   * with headroom; the exact crossing is 0.5907 (#d4433a, 4.50:1), which leaves nothing for a
   * derived stop. AK-SOLID in the matrix is what holds this, for every palette and every look.
   * The DARK block below caps nothing: dark's accent ink is near-black, not white. */
  --ak-accent:        oklch(from var(--color-primary, #e8564a) min(l, 0.576) c h);
  --ak-accent-2:      var(--color-secondary, var(--ak-accent));
  /* THE SPECTRUM: two hues DERIVED from the accent by OKLCh rotation — lightness and chroma do
   * not move, so every contrast ratio the matrix proves for the accent holds for its rotations.
   * This is what lets one brand colour carry an aurora instead of a monochrome wash, without
   * breaking the "a preset never introduces a colour" rule: the spectrum IS the accent. */
  --ak-spectrum-2:    oklch(from var(--ak-accent) l c calc(h + 80));
  --ak-spectrum-3:    oklch(from var(--ak-accent) l c calc(h - 55));
  --ak-accent-ink:    var(--color-primary-content, #ffffff);
  /* The accent as TEXT: pulled toward the ink until small text passes contrast. */
  --ak-accent-text:   color-mix(in oklab, var(--ak-accent) 74%, var(--ak-ink));
  --ak-ok:            var(--color-success, #0f7a45);
  --ak-warn:          var(--color-warning, #8a5300);
  --ak-err:           var(--color-error, #b3261e);
  /* The tones as TEXT (console lines, gauge readings): pulled toward the ink the way
     --ak-accent-text is, so they darken on paper, lighten in the dark, and follow a world's
     own ink (phosphor text on a terminal) — AK-TONE proves every combination. */
  --ak-ok-text:       color-mix(in oklab, var(--ak-ok) 42%, var(--ak-ink));
  --ak-warn-text:     color-mix(in oklab, var(--ak-warn) 36%, var(--ak-ink));
  --ak-err-text:      color-mix(in oklab, var(--ak-err) 42%, var(--ak-ink));
  --ak-focus:         var(--ak-accent);
  /* The one brand gradient — hero band, primary CTA fill. One region per screen. Two HUES now,
   * not two darknesses of one: the spectrum is what makes it read as energy. */
  --ak-grad:          linear-gradient(135deg,
                        color-mix(in oklab, var(--ak-accent) 85%, var(--ak-ink)),
                        color-mix(in oklab, var(--ak-spectrum-2) 74%, var(--ak-ink)));
  /* The scrim hero TEXT sits on — mode-following, composited over image or gradient. */
  --ak-scrim:         color-mix(in oklab, var(--ak-bg) 78%, transparent);
  /* The hero's OWN text colours. Default: the page ink over the pale scrim, and the SUBLINE
   * carries the same colour (hierarchy comes from size — a dimmed subline measured 3.2:1 on the
   * band's real grounds, so dimming is a look's own provable choice, never the default). An
   * inverse-band look (a saturated banner with light type — carnival) points these at the
   * action ink and thins the scrim; AK-SCRIM proves whichever pair is declared. */
  --ak-hero-ink:      var(--ak-ink);
  --ak-hero-ink-dim:  var(--ak-hero-ink);
  /* The zero-image hero ground: an AURORA — four lobes across the derived spectrum, real
   * chroma. The scrim under the text is what AK-SCRIM verifies, so the mesh may commit. */
  --ak-hero-image:    radial-gradient(at 15% 18%, color-mix(in oklab, var(--ak-accent) 36%, var(--ak-bg)), transparent 52%),
                      radial-gradient(at 85% 10%, color-mix(in oklab, var(--ak-spectrum-2) 34%, var(--ak-bg)), transparent 54%),
                      radial-gradient(at 68% 96%, color-mix(in oklab, var(--ak-spectrum-3) 32%, var(--ak-bg)), transparent 56%),
                      radial-gradient(at 4% 86%,  color-mix(in oklab, var(--ak-spectrum-2) 22%, var(--ak-bg)), transparent 46%);
  /* The page's own ambient: the same spectrum, whisper-quiet, under everything — the ground
   * stops being a dead flat and the app has weather. Presets that mean flatness turn it off. */
  /* The page ambient carries the ROTATED hues only — never the accent itself. Leading with the
   * accent at 8% was what smeared warm milk over the whole ground; the spectrum's rotations
   * drift cool and warm against each other, which reads as weather instead of as a stain. */
  --ak-page-image:    radial-gradient(at 96% 8%,   color-mix(in oklab, var(--ak-spectrum-2) 7%, var(--ak-bg)), transparent 46%),
                      radial-gradient(at 6% 104%,  color-mix(in oklab, var(--ak-spectrum-3) 6%, var(--ak-bg)), transparent 50%);
  /* Chrome glass: the bar and the bottom nav float on a blurred, saturated pane. */
  --ak-glass:         color-mix(in oklab, var(--ak-surface) 74%, transparent);
  --ak-blur:          14px;
  /* Film grain — an inline, colourless SVG noise; costs no request and no generation. */
  --ak-grain:         url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n' x='0' y='0' width='100%25' height='100%25'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)' opacity='0.16'/></svg>");

  /* ── Shape and depth ──────────────────────────────────────────────────────────────────── */
  --ak-radius:        var(--radius-box, 14px);
  --ak-radius-sm:     var(--radius-field, 9px);
  --ak-radius-pill:   999px;
  --ak-elev-1:        var(--elev-card, 0 1px 2px rgba(12, 14, 18, 0.06), 0 6px 18px rgba(12, 14, 18, 0.07));
  --ak-elev-2:        var(--elev-raise, 0 10px 30px rgba(12, 14, 18, 0.12));

  /* ── Type ─────────────────────────────────────────────────────────────────────────────── */
  --ak-font:          var(--font-body, ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif);
  --ak-font-display:  var(--font-display, var(--ak-font));
  --ak-font-mono:     var(--font-mono, ui-monospace, 'JetBrains Mono', 'SFMono-Regular', Menlo, monospace);
  --ak-text-hero:     var(--text-hero, clamp(2.2rem, 7vw, 3.6rem));
  --ak-text-title:    var(--text-title, clamp(1.1rem, 2.6vw, 1.4rem));
  --ak-text-body:     var(--text-body, 0.95rem);
  --ak-text-fine:     var(--text-fine, 0.8125rem);     /* 13px floor                         */
  /* THE ONE SIZE UNDER THE FINE FLOOR, and the list of who may use it. A tick label on a chart
   * axis, an edge label on a graph, a time inside a schedule band and a map's licence credit are
   * read beside the thing they annotate, never on their own, and 13px would not fit the box the
   * mark leaves. Nothing else in the kit is allowed below --ak-text-fine: a caption, a hint, a
   * chip and a control's own label all read at the floor. 11px is the bottom (the review measured
   * five places at 9.8 to 10.9 and every one of them fits at 11). */
  --ak-text-micro:    11px;                             /* annotations only, see the list above */
  --ak-weight-display: 750;
  --ak-display-shadow: none;                            /* extrusion under display type      */
  --ak-display-stroke: 0;                               /* outline width around display type */
  --ak-tilt:          0deg;                             /* per-tile rotation (sticker looks) */
  --ak-kinetic:       none;                             /* masthead letter-throw: none|letters|words */
  --ak-page-grain:    none;                             /* page-wide texture tile (paper, phosphor) */

  /* ── Density, space, motion ───────────────────────────────────────────────────────────── */
  --ak-gap:           var(--gap-card, 14px);
  --ak-pad:           16px;
  --ak-touch:         44px;                             /* minimum interactive height        */
  --ak-touch-min:     40px;                             /* the floor a compact control may sit on */
  --ak-scroll-fade:   28px;                             /* the edge fade on a sideways scroller */
  --ak-motion:        var(--motion-base, 200ms);
  --ak-ease:          var(--ease-out, cubic-bezier(0.2, 0.7, 0.3, 1));
  /* Vivid entrance: components rise in, staggered. Flat zeroes both and nothing animates. */
  --ak-enter-distance: 14px;
  --ak-enter-stagger:  40ms;
  /* THE SPRING HAND. --ak-motion is how long a move takes; these three are how it MOVES while it
   * takes it: the physics the kit's spring, drag and staggered entrance sample their keyframes
   * from (motion.js: springFrames reads them off the element when the call names no number).
   * Higher stiffness arrives sooner, lower damping overshoots and settles back, more mass adds
   * weight to both. The house hand is 170/20/1, which lands just short of a bounce. Every look
   * declares its own three, so an author tunes the LOOK and every call follows.
   * MODE-INDEPENDENT ON PURPOSE: a spring is a feel, not a colour, and a card does not want a
   * different bounce at night, so these are declared once here and the dark block below leaves
   * them alone, the way --ak-motion, --ak-ease and the entrance pair already are. */
  --ak-spring-stiffness: 170;
  --ak-spring-damping:   20;
  --ak-spring-mass:      1;
  /* THE AMBIENT (2026-09-05). The one layer allowed to move at idle: a preset id (waves, aurora,
   * dust, grid, static, ink — the registry in src/data/atelier-ambients.ts) or none. THE LOOK
   * DECIDES: every look declares its own three, an app overrides through app({ ambient }), and
   * the viewer's weather switch and the Less-motion switch win over both. Alpha is how much of
   * the layer shows through (0..1); speed is a multiplier on the preset's design speed
   * (0.25..2). Mode-independent like the spring hand: the layer reads its colours off the
   * tokens at run time, so night and day come from the ground, never from a second declaration
   * in the dark block. */
  --ak-ambient:       none;
  --ak-ambient-alpha: 1;
  --ak-ambient-speed: 1;

  /* ── The node's injected bottom controls — never draw under them ──────────────────────── */
  --ak-chrome-bottom: var(--aimeat-chrome-bottom, 56px);

  /* ── Component sizing (one sizing everywhere — instances never override these) ────────── */
  /* ROOM BY DEFAULT (2026-08-29). This was 68rem, and before that 52rem — a lane down the
   * middle with dead margins on every desktop, which the developer rightly called the rule
   * nobody chose. A page now takes the WHOLE window; the composition grid's spans own the line
   * lengths, and the looks that mean READING (editorial, broadsheet, gallery, terminal,
   * neon-dense) set their own measure, because a paragraph at 2000px is not a design choice.
   * Going back to a lane is one token on the look or the app's signature. */
  --ak-main-max:      100%;
  /* The band is sized by what STANDS IN IT, not by a slice of the window. 30dvh meant a title
   * and one line ate a third of a laptop screen before anything was read; the poster looks
   * (poster, carnival, billboard, aurora) still declare their tall bands on purpose. */
  --ak-hero-min:      11rem;
  /* The broadcast family's channel colours and the set's ground (mtv.css reads them): four
     spectrum hues with television defaults, retuned by a look under the matrix's proof. */
  --ak-crt-ch1:       #24e5ff;
  --ak-crt-ch2:       #ff2e9a;
  --ak-crt-ch3:       #ffe14d;
  --ak-crt-ch4:       #38f2a0;
  --ak-crt-set:       #14101f;

  /* ── PER-COMPONENT TOKENS (0.51.0) ──────────────────────────────────────────────────────
   * The rule of this contract is that a value a builder would reach for is a variable, and
   * until now that held for the LOOK's values and not for one component's. These are the
   * sizes that were literals inside a component's own rules: an app sets one on its own box
   * ("--ak-list-aside-size: 1.75rem" on a wrapper) and changes exactly that part, in every
   * look and both modes, with no .ak-* selector overridden. Every default below is the value
   * the component already had, so nothing moves until somebody moves it.
   * ────────────────────────────────────────────────────────────────────────────────────── */
  --ak-list-gap:          8px;                  /* between rows                              */
  --ak-list-row-gap:      var(--ak-gap);        /* words to the right-hand side              */
  --ak-list-row-pad-y:    10px;
  --ak-list-row-pad-x:    var(--ak-pad);
  --ak-list-line-gap:     2px;                  /* title to sub to the third line            */
  --ak-list-aside-size:   var(--ak-text-body);  /* the right-hand figure                     */
  --ak-card-min:          11rem;                /* the grid's narrowest card                 */
  --ak-card-gap:          var(--ak-gap);
  --ak-card-aspect:       4 / 3;
  --ak-card-pad:          var(--ak-pad);
  --ak-table-cell-pad-y:  10px;
  --ak-table-cell-pad-x:  var(--ak-pad);
  --ak-timeline-dot:      12px;
  --ak-timeline-gap:      var(--ak-gap);
  --ak-timeline-rail:     var(--ak-pad);        /* the drop under each event                 */
  --ak-timeline-indent:   5px;                  /* where the rail stands                     */
  --ak-stat-min:          9.5rem;
  --ak-stat-gap:          var(--ak-gap);
  --ak-stat-pad:          var(--ak-pad);
  --ak-stat-figure-size:  var(--ak-text-title);
  --ak-stat-unit-size:    var(--ak-text-fine);
  --ak-stat-up:           var(--ak-ok-text);    /* the direction marks, tone-derived         */
  --ak-stat-down:         var(--ak-err-text);
  --ak-hero-pad:          var(--ak-pad);
  --ak-hero-gap:          6px;
  --ak-hero-title-size:   var(--ak-text-hero);
  --ak-section-pad:       var(--ak-pad);
  --ak-section-gap:       8px;
  --ak-queue-row-pad-y:   9px;
  --ak-queue-state-min:   72px;
  --ak-health-lamp:       11px;
  --ak-health-row-pad-y:  10px;
  --ak-kanban-col-min:    13rem;
  --ak-kanban-card-pad:   10px;
  --ak-kanban-gap:        calc(var(--ak-gap) * 0.75);
  --ak-tabs-gap:          6px;
  --ak-range-track:       6px;                  /* the slider's rail                         */
  --ak-range-thumb:       22px;                 /* the grip; the hit area is --ak-touch      */
}

/* ══════════════════════════════════════════════════════════════════════════════════════════
   THE CONTRACT — dark. Same names, dark literals. A look re-declares only what it changes.
   ══════════════════════════════════════════════════════════════════════════════════════════ */
/* @preset-block vivid-dark */
:root[data-theme='dark'] {
  /* Dark with a SOUL: the surfaces lean toward the accent instead of sitting on neutral grey —
   * the "sieluton harmaa" verdict was about exactly these three tokens. A few percent of hue
   * on a near-black ground changes the temperature of the whole app without touching a single
   * contrast number the matrix cannot see. */
  --ak-bg:          color-mix(in oklab, var(--ak-accent) 4%, var(--color-base-100, #0f1218));
  --ak-surface:     color-mix(in oklab, var(--ak-accent) 7%, var(--color-base-200, #171b23));
  --ak-surface-2:   color-mix(in oklab, var(--ak-accent) 5%, var(--color-base-100, #10141a));
  --ak-ink:         var(--color-base-content, #e7ebf2);
  --ak-line:        color-mix(in oklab, var(--ak-accent) 12%, var(--color-base-300, #2b323d));
  --ak-accent:      var(--color-primary, #ff6f62);
  --ak-accent-ink:  var(--color-primary-content, #1a0d0b);
  --ak-ok:          var(--color-success, #43c98a);
  --ak-warn:        var(--color-warning, #e0a33a);
  --ak-err:         var(--color-error, #f2695c);
  /* Dark raises the scrim so one image survives both modes with readable text. */
  --ak-scrim:       color-mix(in oklab, var(--ak-bg) 62%, transparent);
  --ak-elev-1:      var(--elev-card, 0 1px 2px rgba(0, 0, 0, 0.4), 0 6px 18px rgba(0, 0, 0, 0.35));
  /* Raised things GLOW in the dark, faintly — depth reads as light, not as a grey blur. */
  --ak-elev-2:      0 10px 30px rgba(0, 0, 0, 0.5), 0 0 26px color-mix(in oklab, var(--ak-accent) 16%, transparent);
  /* The channel colours are the same in the dark: a television glows the same at night. */
  --ak-crt-ch1:     #24e5ff;
  --ak-crt-ch2:     #ff2e9a;
  --ak-crt-ch3:     #ffe14d;
  --ak-crt-ch4:     #38f2a0;
  --ak-crt-set:     #14101f;
}

/* ══════════════════════════════════════════════════════════════════════════════════════════
   LOOK PRESETS live in ./aimeat-atelier/looks.css — GENERATED from src/data/atelier-looks.ts
   (pnpm build:atelier-looks). One registry drives the stylesheet, the build prompt's look
   table and the mosaic catalogue; pnpm check:atelier refuses drift and runs the full matrix
   over every generated block. A new look is one data entry, and the growth rule (matrix green
   plus a reviewed diagonal, TARGET-074) is enforced by the gate instead of remembered.
   ══════════════════════════════════════════════════════════════════════════════════════════ */

/* ══════════════════════════════════════════════════════════════════════════════════════════
   Reduced motion: every animated thing collapses to its end state.

   THE PSEUDO-ELEMENTS ARE PART OF "EVERY". `.ak-root *` matches elements, and a pseudo-element
   is not one: for a year the hero's aurora drift lived on `.ak-hero::before` and kept wandering
   forever under prefers-reduced-motion because this block never reached it, while the
   ambient layer beside it was safe only because ambient.css names its own `animation: none`.
   The four selectors below are the whole surface a declaration can be attached to, so a new
   decorative layer is caught whether it is an element or a mark painted by one.

   AND THREE VOICES REACH IT, NOT ONE. The operating system's setting was the only one this block
   ever heard, so the bar's own Less-motion switch quieted every SCRIPT in the kit (they all ask
   reducedMotion()) and left every CSS entrance, shimmer and lift running behind it — the switch
   said "less" and the stylesheet carried on. `html[data-ak-motion="less"]` is that switch, and
   `[data-ak-motion-defaults="off"]` is an app's `motion: false` or a block's; all three land in
   the same three declarations.
   ══════════════════════════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  .ak-root, .ak-root *,
  .ak-root::before, .ak-root::after,
  .ak-root *::before, .ak-root *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
}

html[data-ak-motion='less'] .ak-root,
html[data-ak-motion='less'] .ak-root *,
html[data-ak-motion='less'] .ak-root::before,
html[data-ak-motion='less'] .ak-root::after,
html[data-ak-motion='less'] .ak-root *::before,
html[data-ak-motion='less'] .ak-root *::after,
[data-ak-motion-defaults='off'],
[data-ak-motion-defaults='off'] *,
[data-ak-motion-defaults='off']::before,
[data-ak-motion-defaults='off']::after,
[data-ak-motion-defaults='off'] *::before,
[data-ak-motion-defaults='off'] *::after {
  animation-duration: 1ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 1ms !important;
}
