:root {
    /* Ship 1 — accent is ONE token, value per surface. This surface (AgriSmart company dashboard) = hay.
       (operator = blue, farmer/public = green.) `--as-accent` is the bar/fill; `--as-accent-ink` is the
       legible-on-white label shade (hay itself is too light for text on white). */
    --as-accent: #C9A66B;          /* hay/straw — tunable, change here only */
    --as-accent-ink: #A0782F;      /* darker hay for accent labels on white (contrast) */
    /* OTA surface (the accounting expert's own face, agcore /ota): its colours are tokens HERE, so a surface that reads
       this gallery (agcore) holds no colour value of its own (DE-21, DE-23). Decided by Peter 14 Nov: plum from Tine's two
       values (lighter one as the accent so it reads as a button, the other as the pressed state), anthracite sampled from
       the OTA character sheet (Tine may replace it). Changing any of them is the one line below.
       --as-ota-accent = plum (buttons, active states, links, focus); --as-ota-accent-pressed = its pressed state;
       --as-ota-accent-hover = the same hue lighter (DE-14 state set, no new colour); --as-ota-dark = anthracite
       (hero block, headings, top band). White text on each passes WCAG AA. */
    --as-ota-accent: #743A54;
    --as-ota-accent-pressed: #6A324A;
    --as-ota-accent-hover: color-mix(in srgb, var(--as-ota-accent) 88%, white);
    --as-ota-dark: #413F44;
    /* The OTA surface's other palette roles (Peter 14 Nov: ALL colours of a surface follow its scheme). Neutral roles reuse the
       one grey family (DE-07) and the one white, so nothing new is born: a surface reads its roles by these names. */
    --as-ota-card: var(--as-white);          /* white cards (DE-11) */
    --as-ota-page: var(--as-grey-bg);        /* the light grey page (DE-11, DE-24) */
    --as-ota-border: var(--as-grey-line);    /* borders */
    --as-ota-ink: var(--as-ink);             /* body text */
    --as-ota-muted: var(--as-grey);          /* secondary text */
    --as-ota-link: var(--as-ota-accent);     /* links (never underlined, DE-19) */
    /* Ship 2 — exactly ONE green (brand/farmer). Success/done REUSE it. No second green. */
    --as-green: #2E5E3E;
    /* TS-ADA-CANVAS-V1-01 - OTA's (internal key ada) accent, a surface accent per DE-03/DE-23: graphite, option B
       (Peter 08.11.2026 19:29 local, Web Claude 20261108T183000Z). An accent only, never neutral text or borders (DE-07).
       Read through the expert's accent_token; change here only. */
    --as-ada: #4A5058;
    /* The other experts' accents (Tine's expert profiles via Lane C 20261108T225000Z; white text on each: TOM 10.8,
       TEA 6.8, LEO 9.2 contrast). The experts registry names the token; status off until each expert goes live. */
    --as-tom: #2C3E5C;   /* navy */
    --as-tea: #7A5230;   /* brown */
    --as-leo: #7A2E3A;   /* bordeaux */
    /* Web Claude 20261108T173300Z / Peter 18:27 local: the APP design tokens (AVA, ADA and every expert's app on web,
       /m and the Expo app), from the Expo theme (theme.js, ToolsScreen.js). One green, one ADA colour, nothing new. */
    --app-accent: var(--as-green);       /* Expo COLORS.primary; AVA's accent; success/done reuse it (DE-06) */
    --app-accent-ada: var(--as-ada);     /* ADA's accent, the same on web, /m and Expo */
    --app-accent-tom: var(--as-tom);     /* each expert's accent reads its own --as-* token (DE-03) */
    --app-accent-tea: var(--as-tea);
    --app-accent-leo: var(--as-leo);
    --app-on: var(--as-white);           /* Expo textLight: text on the accent */
    --app-bg: var(--as-grey-bg);         /* Expo background */
    --app-card: var(--as-white);         /* Expo surface / card */
    --app-ink: var(--as-ink);            /* Expo text */
    --app-muted: var(--as-grey);         /* Expo textSecondary */
    --app-line: var(--as-grey-line);     /* Expo border */
    --app-radius-tile: 16px;             /* Expo RADIUS.lg (toolCard, weather strip) */
    --app-radius-button: 8px;            /* Expo RADIUS.md (settingsButton, day card) */
    --app-gap: 16px;                     /* Expo SPACING.md */
    --app-pad-tile: 24px;                /* Expo SPACING.lg */
    --app-pad-button: 16px;              /* Expo SPACING.md */
    --app-fs-tile: 1.25rem;              /* Expo toolName 20 */
    --app-fs-button: 0.875rem;           /* Expo FONTS.sizes.md 14 */
    --app-fs-small: 0.75rem;             /* Expo FONTS.sizes.sm 12 */
    /* semantic colours are their own tokens, unaffected by the one-green rule */
    --as-error: #C0392B;
    --as-warning: #B7791F;
    /* TS-IMPL-GALLERY-DESIGN-FIXES fix 5 — the ONE canonical tag/pill. Each variant is a subtle tinted
       background + a darker INK OF THE SAME HUE; no loud saturated fills. Neutral (grey) is the default;
       a semantic variant is used only where the meaning matters. Success ink reuses the one green
       (--as-green, DE-06) and error/warn reuse the existing semantic tokens — no new colour is born. */
    --as-tag-neutral-bg: #EDEDEA; --as-tag-neutral-ink: var(--as-grey);
    --as-tag-success-bg: #E7F1EA; --as-tag-success-ink: var(--as-green);
    --as-tag-error-bg:   #FBEAEC; --as-tag-error-ink:   var(--as-error);
    --as-tag-warn-bg:    #FBF1E2; --as-tag-warn-ink:    var(--as-warning);
    /* Status-dot meanings (kept per Peter's review — these carry legend meaning, unlike button dots). */
    --as-dot-idle: #B4B2A9; --as-dot-ready: var(--as-green); --as-dot-live: var(--as-error);
    /* TS-IMPL-GALLERY-DESIGN-FIXES fix 6 — VERTICAL RHYTHM, defined once. Rows were cramped (the
       taxonomy/publish rows read tight). --as-row-y is the one up/down value every stacked row (table
       row, list row, form row) uses, so row height is tuned HERE and follows everywhere.
       This surface had no spacing scale at all — the 4/8/12/16/24 step scale is defined here with it. */
    --as-space-xs: 4px; --as-space-sm: 8px; --as-space-md: 12px; --as-space-lg: 16px; --as-space-xl: 24px;
    --as-row-y: var(--as-space-md);    /* 12px up/down inside a row — was 8px */
    --as-row-x: var(--as-space-md);    /* 12px left/right, paired so cells read evenly */
    --as-stack-y: var(--as-space-lg);  /* 16px between stacked blocks/form rows */
    /* Ship 2b — ONE grey family (one hue; a minimal legible scale, not one literal value — a single value
       can't serve dark text AND light borders). Collapses the old slate + #333/#666/#ddd families. */
    --as-ink: #2B2B2B;             /* primary text (darkest grey step) */
    --as-grey: #6B6B6B;            /* the one grey — muted/secondary text */
    --as-grey-line: #DADAD6;       /* borders (light step of the same hue) */
    --as-grey-bg: #F4F4F1;         /* neutral surface (lightest step) */
    --as-white: #FFFFFF;
    /* Ship 3 — typography central tokens (font family + named size scale). No surface hardcodes these. */
    --as-font: -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
    --as-fs-xs: 0.72rem; --as-fs-sm: 0.82rem; --as-fs-md: 0.92rem; --as-fs-lg: 1.05rem; --as-fs-xl: 1.4rem;
    --as-fw-normal: 400; --as-fw-medium: 600; --as-fw-bold: 700;
    /* Ship 4 — flat: no shadows anywhere. Radius tokens. */
    --as-radius: 9px;
    --as-radius-lg: 12px;   /* larger radius for cards / tables / modals (was hardcoded 12px) */
    /* TS-IMPL-GALLERY-DEFINE-ALL-ELEMENTS — fixed control heights so buttons/inputs never drift and align in a row. */
    --as-ctrl-h: 34px;      /* normal control height (button / input / select) */
    --as-ctrl-h-sm: 26px;   /* compact (.sm) control height */
    --as-ctrl-h-lg: 42px;   /* large (.lg) control height */
    /* ── TS-fix-DESIGN-RESPONSIVE-RULES — WIDTH, the vocabulary this file did not have ──────────────
       Colour, type, spacing, radius and control height were all defined here; width, overflow and
       wrapping were not. So "narrow" had no meaning, no rule could refer to it, and 1,213 of 1,511
       layout sites across the surfaces had no protection — including 134 of 140 tables.

       TOKENS OF RECORD. A custom property CANNOT be used inside an @media CONDITION: the condition is
       evaluated before the cascade, so `@media (max-width: var(--as-bp-md))` simply does not work.
       These four widths are therefore the documented single set that every @media in the system types
       out literally — exactly as --as-fs-* is the single set of type sizes. A surface that invents its
       own width is a second design system (DE-01/DE-21). Outside a media condition they are ordinary
       tokens and MUST be used as such (see --as-w-table-min below).

       The scale is Tailwind's, because mon-dash already ships Tailwind — building on what exists rather
       than beside it (SW-01/CC-09). Peter's decision, 2026-08-05. */
    --as-bp-sm: 640px; --as-bp-md: 768px; --as-bp-lg: 1024px; --as-bp-xl: 1280px;
    /* The narrowest width the system undertakes to stay usable at, on every surface. "Does it work when
       narrow?" now has one answer that both a person and a gate can test against. Peter's decision. */
    --as-w-min: 320px;
    /* The floor a data table stops shrinking at; below it, its container scrolls sideways (see .d-table).
       Derived from the scale above, so it is not a fifth width — and it is the ONE place to tune how
       early a table starts scrolling. */
    --as-w-table-min: var(--as-bp-sm);
    /* TS-FIX-AMAS-IPHONE-APP-V1-01 Ship 3 — TOUCH, the two values a phone needs that a mouse does not.
       --as-touch-min: the smallest tap target (Apple HIG 44pt). Below --as-bp-md the control-height
       tokens are raised to it, so every .d-btn / .d-input / .d-tab / nav item becomes tappable at once.
       --as-fs-touch-input: iOS Safari zooms the whole page when a focused field is below 16px; 1rem is
       that floor. Both are tokens, so the values live here and nowhere else. */
    --as-touch-min: 44px;
    --as-fs-touch-input: 1rem;
    /* TS-FIX-AMAS-IPHONE-POLISH-V1-01 G2 — THE PHONE CONDITION OF RECORD. A phone is narrower than
       --as-bp-md, OR it is a touch device less than 500px tall: a phone held sideways is 844-956px wide,
       so a width-only rule switched the phone layout OFF in landscape and served the desktop page. A
       mouse is pointer:fine and a tablet is at least 744px tall, so neither ever matches the second
       half. Every @media for "phone" in every surface types exactly this condition:
           @media (max-width: 768px), (max-height: 500px) and (pointer: coarse)
       (a custom property cannot sit in a media condition - see the width tokens above). Script reads
       the same condition from --as-mq-phone with matchMedia(), so JS and CSS agree by construction. */
    --as-mq-phone: "(max-width: 768px), (max-height: 500px) and (pointer: coarse)";
    /* TS-FIX-AMAS-IPHONE-POLISH-V1-01 G3/G5 — three phone values.
       --as-scrim: the dimmed page behind a modal or a menu sheet (the value .d-modal-overlay always used).
       --as-compact-field-max: how tall a compact reply field may grow with its text
         (.d-actionbar.is-compact) - a third of the visible height, so the conversation stays in view.
       --as-counter-w: the room a list row keeps free on its right for a small corner counter/timer, so
         the counter never sits on top of the row's text. */
    --as-scrim: rgba(43,43,43,0.5);
    --as-compact-field-max: 30dvh;
    --as-counter-w: 4rem;
    /* TS-IMPL-COMPONENTS-01 — the shared focus-visible ring (accessibility). ONE token, used by every
       interactive component's :focus-visible. Hay ring on this surface. This closes the a11y gap the
       component audit flagged (focus-visible = 0 everywhere; 57 outline:none with no replacement). */
    --as-ring: rgba(201,166,107,0.55);
    /* Canonical components are themed by --sfc-* so ONE definition serves every surface (the Design gallery
       overrides these per [data-subsection] to preview Web/Backoffice/Mobile). On the real AgriSmart tabs
       the surface IS AgriSmart, so the defaults = the hay accent. */
    --sfc-accent: var(--as-accent);
    --sfc-on: var(--as-ink);            /* on-accent text (hay is light → dark ink) */
    --sfc-soft: rgba(201,166,107,0.22);
    --sfc-ring: var(--as-ring);
    /* The accent shade that stays legible as TEXT ON WHITE. Hay itself is too light, so this surface
       maps to the darker hay; on a dark accent (operator blue) the accent itself is already legible and
       the surface maps this straight to --sfc-accent. Named the same in every surface so one definition
       (e.g. .d-nav-item.active) serves them all. */
    --sfc-accent-ink: var(--as-accent-ink);
    /* ── PAGE BACKGROUND (DE-24) — a role, surface-owned like the accent (DE-23). ──
       This value is AgriSmart's page background. Each landscape overrides it at its own level:
         AgriSmart   #F4F4F1  (the warm neutral, below)
         Dashboards  #F5F7FA  (mon-dash's operator page, set in unified-design-system.css)
         AVA Web / Web UI / Mobile — set theirs when they connect; the gallery previews them per
         [data-subsection] on the Design tab, alongside each surface's accent.
       Nothing else may set a page background. */
    --surface-bg: var(--as-grey-bg);
    /* Chat bubble roles (surface-owned colour, DE-23): "me" = the person, "them" = the assistant. Defaults keep the
       existing look; a surface block may set its own. */
    --bubble-me-bg: var(--sfc-accent); --bubble-me-ink: var(--sfc-on); --bubble-me-border: transparent;
    --bubble-them-bg: var(--as-grey-bg); --bubble-them-ink: var(--as-ink); --bubble-them-border: transparent;
    /* A DEFINED state of the page surface, not a stray: the Task-status screen washes the whole page in
       this when every handed-over task is done. Green here always means DONE. */
    --surface-bg-done: var(--as-tag-success-bg);
  }
:root[data-surface="app"], [data-surface="app"], :root[data-surface="farmer"], [data-surface="farmer"], [data-subsection="mobile"], [data-subsection="app"] {
    --as-accent: var(--as-green);            /* Expo COLORS.primary #2E5E3E = the one green (DE-06) */
    --as-accent-ink: var(--as-green);
    --sfc-accent: var(--app-accent);
    --sfc-accent-ink: var(--app-accent);
    --sfc-on: var(--as-white);               /* Expo textLight on the green header, tab bar and buttons */
    --sfc-soft: rgba(46,94,62,0.12);
    --sfc-ring: rgba(46,94,62,0.35);
    --as-ring: rgba(46,94,62,0.35);
    --surface-bg: var(--as-grey-bg);         /* Expo background #F5F5F5 ~ the one grey background (DE-07) */
    /* Expo chat: the assistant speaks in the green bubble, the person's own message is white with a border */
    --bubble-them-bg: var(--as-green); --bubble-them-ink: var(--as-white); --bubble-them-border: transparent;
    --bubble-me-bg: var(--as-white); --bubble-me-ink: var(--as-ink); --bubble-me-border: var(--as-grey-line);
  }
:root[data-expert="ada"], [data-expert="ada"] { --app-accent: var(--app-accent-ada); --sfc-accent: var(--app-accent-ada);
    --sfc-accent-ink: var(--app-accent-ada); --bubble-them-bg: var(--app-accent-ada); }
:root[data-expert="tom"], [data-expert="tom"] { --app-accent: var(--app-accent-tom); --sfc-accent: var(--app-accent-tom);
    --sfc-accent-ink: var(--app-accent-tom); --bubble-them-bg: var(--app-accent-tom); }
:root[data-expert="tea"], [data-expert="tea"] { --app-accent: var(--app-accent-tea); --sfc-accent: var(--app-accent-tea);
    --sfc-accent-ink: var(--app-accent-tea); --bubble-them-bg: var(--app-accent-tea); }
:root[data-expert="leo"], [data-expert="leo"] { --app-accent: var(--app-accent-leo); --sfc-accent: var(--app-accent-leo);
    --sfc-accent-ink: var(--app-accent-leo); --bubble-them-bg: var(--app-accent-leo); }