/* ==========================================================================
   Cyber City · UI foundations v0.3 · 2026-10-02
   Identity-level components for the `ecc` theme. Every colour, size, radius, duration, easing and layer
   comes from tokens.css (--ecc-*). Load order: tokens.css, fonts.css, pixel-kit.css, then this file.
   Icons come from icons/sprite.svg (icons.md). Motion rules: motion.md.
   Day   = direction B: flat modules 8px apart, ink primary button with a lime pip. Day is the default theme.
   Night = direction A: borders and light instead of shadows, lime primary button. Only by the visitor's switch.
   Dark panels: put .ecc-ctx-panel (tokens.css) on the panel and every control inside reads correctly.
   The product stage itself is the pixel kit's .pk-stage (pixel-kit.css); the card around it is here.

   WHO NAMES AND WHO SPEAKS (the store that explains)
   Mono capitals (.ecc-mono) NAME things: departments, categories, section notes, spec keys, status.
   Archivo in sentence case SPEAKS: promises (claims), form labels, questions, anything written as a sentence.
   Navigation, breadcrumbs, tabs and pagination keep the look that was approved: short names in mono capitals.
   So: a label over a field is a sentence ("Your name"), never capitals. A promise is a claim (11), never a badge (10).

   Contents
   1 base, focus, selection · 2 type helpers and icons · 3 module grid · 4 controls: state changes, buttons · 5 links · 6 fields
   7 check, radio, switch · 8 quantity stepper · 9 chips · 10 badges · 11 claims and answers · 12 product card · 13 spec table
   14 alerts · 15 breadcrumbs · 16 pagination · 17 tabs · 18 accordion · 19 tooltip · 20 toast · 21 skeleton
   22 empty state · 23 drawer · 24 reduced motion · 25 forced colours (Windows high contrast)
   Forced states for the style guide: .is-hover · .is-focus · .is-pressed · .is-open · .is-sheet (same look as the real state).
   ========================================================================== */

/* ================================================================= 1 · BASE */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--ecc-canvas); color: var(--ecc-ink);
  font-family: var(--ecc-f-text); font-size: var(--ecc-t-body); line-height: var(--ecc-lh-body);
  font-weight: var(--ecc-fw-text); font-stretch: var(--ecc-wdth-text);
  -webkit-font-smoothing: antialiased;
}
img { display: block; max-width: 100%; }
a { color: inherit; }
button, input, select, textarea { font: inherit; color: inherit; }
h1, h2, h3, h4, p, dl, dd, figure { margin: 0; }
[hidden] { display: none !important; }

/* the focus ring recipe: one ring for every control, in the theme's focus colour */
:focus-visible, .is-focus { outline: var(--ecc-focus-ring); outline-offset: var(--ecc-focus-offset); }
/* A control that is itself a dark panel (the header logo tile: the first Tab stop of every page) carries the lime ring of
   .ecc-ctx-panel. Drawn outside the panel, lime lands on the light canvas in Day: 1.18:1. So this ring is drawn inside the
   panel, --ecc-focus-offset in from its edge: lime with the dark surface on both of its sides, 13.29:1 in Day. */
.ecc-ctx-panel:focus-visible, .ecc-ctx-panel.is-focus { outline-offset: calc((var(--ecc-focus-width) + var(--ecc-focus-offset)) * -1); }

/* text selection: the inverse of the text around it (--ecc-selection-*, 16.89:1 by day, 16.98:1 at night). The pair takes its
   Night values inside .ecc-ctx-panel. Never lime: a selection can cover a whole page. */
::selection { background: var(--ecc-selection-bg); color: var(--ecc-selection-fg); }

.ecc-sr-only { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.ecc-skip { position: absolute; left: 12px; top: -80px; z-index: var(--ecc-z-sticky); padding: 12px 16px; border-radius: var(--ecc-r-sm); background: var(--ecc-panel); color: var(--ecc-on-panel); }
.ecc-skip:focus { top: 12px; }

/* ========================================================= 2 · TYPE HELPERS */
.ecc-display { font-size: var(--ecc-t-display); line-height: var(--ecc-lh-display); letter-spacing: var(--ecc-ls-display); font-weight: var(--ecc-fw-display); font-stretch: var(--ecc-wdth-display); }
.ecc-h1 { font-size: var(--ecc-t-h1); line-height: var(--ecc-lh-heading); letter-spacing: var(--ecc-ls-heading); font-weight: var(--ecc-fw-display); font-stretch: var(--ecc-wdth-display); }
.ecc-h2 { font-size: var(--ecc-t-h2); line-height: var(--ecc-lh-heading); letter-spacing: var(--ecc-ls-heading); font-weight: var(--ecc-fw-strong); font-stretch: var(--ecc-wdth-title); }
.ecc-h3 { font-size: var(--ecc-t-h3); line-height: 1.2; letter-spacing: var(--ecc-ls-heading); font-weight: var(--ecc-fw-strong); font-stretch: var(--ecc-wdth-heading); }
.ecc-lead { font-size: var(--ecc-t-body-lg); line-height: 1.5; color: var(--ecc-ink-2); }
.ecc-muted { color: var(--ecc-ink-2); }
/* mono label: uppercase, 13px (12px with --micro, the floor) */
.ecc-mono {
  font-family: var(--ecc-f-mono); font-size: var(--ecc-t-label); line-height: 1.4; letter-spacing: var(--ecc-ls-label);
  text-transform: uppercase; font-stretch: var(--ecc-wdth-mono); font-weight: var(--ecc-fw-mono);
}
.ecc-mono--micro { font-size: var(--ecc-t-micro); }
/* dot-matrix readout: numerals and short marks only. Never under 20px; on a light surface never under 24px,
   and at 24px in weight 900 (typography.md 6: at 20px on light the round dots are too thin on a standard screen) */
.ecc-dot { font-family: var(--ecc-f-dot); font-variation-settings: var(--ecc-dot-settings); font-weight: var(--ecc-fw-dot); line-height: 1; letter-spacing: .04em; }
/* the pip: the logo's voxel, the system's bullet */
.ecc-pip { display: inline-block; flex: none; width: 8px; height: 8px; border-radius: var(--ecc-r-voxel); background: var(--ecc-spark); }
/* Icons (icons.md): <svg class="ecc-icon" width="24" height="24" aria-hidden="true" focusable="false"><use href="#ecc-i-name"/></svg>
   The size comes from the width and height attributes (16, 20, 24, 32 or 48), never from em, so the 1.5-unit grid
   lands on whole pixels. An icon takes the colour of the text beside it. Two hooks reach into the sprite:
   the spark of a department icon (lit on the current one) and the fill of a heart or a star. */
.ecc-icon { display: inline-block; flex: none; vertical-align: middle; }
.is-on > .ecc-icon { --ecc-icon-spark: var(--ecc-spark); }
.is-filled > .ecc-icon { --ecc-icon-fill: currentColor; }

/* ========================================================== 3 · MODULE GRID */
/* 12 columns, modules 8px apart like parts on a chassis. Day modules are flat; at night they get a graphite border. */
.ecc-wrap { max-width: calc(var(--ecc-container) + 144px); margin: 0 auto; padding: var(--ecc-gap); }
.ecc-grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--ecc-gap); }
.ecc-span-2 { grid-column: span 2; } .ecc-span-3 { grid-column: span 3; } .ecc-span-4 { grid-column: span 4; } .ecc-span-5 { grid-column: span 5; }
.ecc-span-6 { grid-column: span 6; } .ecc-span-7 { grid-column: span 7; } .ecc-span-8 { grid-column: span 8; } .ecc-span-12 { grid-column: span 12; }
.ecc-module {
  position: relative; min-width: 0;
  border-radius: var(--ecc-r); background: var(--ecc-surface); color: var(--ecc-ink);
  box-shadow: var(--ecc-elev-module);
}
.ecc-module--pad { padding: 28px; }
.ecc-module--alt { background: var(--ecc-surface-2); }
.ecc-module--panel { background: var(--ecc-panel); }      /* pair with .ecc-ctx-panel */
.ecc-module--panel-2 { background: var(--ecc-panel-2); }  /* pair with .ecc-ctx-panel */
/* chrome stays light in both themes, so its inks are fixed, and so is its selection (dark on the light tile, also at night) */
.ecc-module--chrome { background: var(--ecc-chrome); color: var(--ecc-on-chrome); --ecc-ink: var(--ecc-on-chrome); --ecc-ink-2: var(--ecc-on-chrome-2); --ecc-selection-bg: var(--ecc-on-chrome); --ecc-selection-fg: var(--ecc-chrome); box-shadow: none; }
.ecc-module--chrome .ecc-pip { background: var(--ecc-on-chrome); }
.ecc-module--stage { background: var(--ecc-stage-bg); }
.ecc-module.is-raised { box-shadow: var(--ecc-elev-raised); }
.ecc-module__label { display: flex; align-items: center; gap: 8px; margin: 0 0 16px; color: var(--ecc-ink-2); }

/* section head: dot-matrix number, title, a mono note */
.ecc-sec { margin-top: var(--ecc-s-8); scroll-margin-top: 12px; }
.ecc-sec__head {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: end; gap: 12px 18px;
  padding: 0 8px 16px; margin-bottom: var(--ecc-gap); border-bottom: 1px solid var(--ecc-line-strong);
}
.ecc-sec__num { font-size: 30px; color: var(--ecc-ink); }
.ecc-sec__note { color: var(--ecc-ink-2); text-align: right; padding-bottom: 4px; }

@media (max-width: 1180px) {
  .ecc-grid > .ecc-span-2, .ecc-grid > .ecc-span-3, .ecc-grid > .ecc-span-4, .ecc-grid > .ecc-span-5 { grid-column: span 6; }
  .ecc-grid > .ecc-span-7, .ecc-grid > .ecc-span-8 { grid-column: span 12; }
}
@media (max-width: 760px) {
  .ecc-grid > [class*="ecc-span-"] { grid-column: span 12; }
  .ecc-module--pad { padding: 22px 18px; }
  .ecc-sec { margin-top: var(--ecc-s-7); }
  .ecc-sec__head { grid-template-columns: auto minmax(0, 1fr); }
  .ecc-sec__note { grid-column: 1 / -1; text-align: left; padding: 0; }
}

/* ==================================================== 4 · CONTROLS, BUTTONS */
/* State changes, one rule for every control (motion.md 6). The colour answers in --ecc-d-fast. While a control is
   held it sits --ecc-press (1px) lower, and it gets there in --ecc-d-press (90ms). `translate` is used, not
   `transform`, so transforms stay free for layout, for the motion layer and for GSAP.
   .is-pressed shows the pressed state in the style guide. */
.ecc-btn, .ecc-iconbtn, .ecc-chip, .ecc-chip__x, .ecc-stepper__btn, .ecc-tab, .ecc-pager a, .ecc-tip__btn, .ecc-claim {
  transition: background-color var(--ecc-d-fast) var(--ecc-ease-out), border-color var(--ecc-d-fast) var(--ecc-ease-out),
    color var(--ecc-d-fast) var(--ecc-ease-out), translate var(--ecc-d-press) var(--ecc-ease-out);
}
:is(.ecc-btn, .ecc-iconbtn, .ecc-chip:not(.ecc-chip--removable), .ecc-chip__x, .ecc-stepper__btn, .ecc-tab, .ecc-pager a, .ecc-tip__btn, .ecc-claim:not(.ecc-claim--static)):active,
.is-pressed { translate: 0 var(--ecc-press); }
:is(.ecc-btn, .ecc-iconbtn, .ecc-chip, .ecc-chip__x, .ecc-stepper__btn, .ecc-tab, .ecc-tip__btn):disabled,
.ecc-btn[aria-disabled="true"] { translate: none; }

.ecc-btn {
  --_bg: transparent; --_fg: var(--ecc-ink); --_line: transparent;
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 48px; min-width: var(--ecc-hit); padding: 0 22px;
  border: 1px solid var(--_line); border-radius: var(--ecc-r-sm);
  background: var(--_bg); color: var(--_fg);
  font-family: var(--ecc-f-text); font-size: var(--ecc-t-body); font-weight: var(--ecc-fw-strong); font-stretch: var(--ecc-wdth-text); line-height: 1;
  text-decoration: none; white-space: nowrap; cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.ecc-btn--sm { min-height: var(--ecc-hit); padding: 0 16px; font-size: .9375rem; }
.ecc-btn--block { width: 100%; }

/* primary: ink with a lime pip by day; lime at night and on dark panels */
.ecc-btn--primary { --_bg: var(--ecc-btn-bg); --_fg: var(--ecc-btn-fg); }
.ecc-btn--primary::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: var(--ecc-r-voxel); background: var(--ecc-btn-pip); }
.ecc-btn--secondary { --_line: var(--ecc-control-line); }
.ecc-btn--ghost { padding: 0 10px; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 6px; }
.ecc-btn--danger { --_bg: var(--ecc-danger-solid); --_fg: var(--ecc-on-danger); }
/* tile: the action inside a product card or a repeated row. An outline in both themes (an ink line by day, the control
   line at night) with a spark pip: lime ink on light, lime on dark. A grid of products then shows no row of filled
   buttons, and the page keeps one filled button per view: its primary. Hover and pressed add the wash. */
.ecc-btn--tile { --_bg: var(--ecc-btn-tile-bg); --_fg: var(--ecc-btn-tile-fg); --_line: var(--ecc-btn-tile-line); }
.ecc-btn--tile::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: var(--ecc-r-voxel); background: var(--ecc-spark); }

@media (hover: hover) and (pointer: fine) {
  .ecc-btn--primary:hover { --_bg: var(--ecc-btn-hover); }
  .ecc-btn--secondary:hover { --_bg: var(--ecc-wash); --_line: var(--ecc-ink); }
  .ecc-btn--ghost:hover { text-decoration-color: var(--ecc-spark); text-decoration-thickness: 2px; }
  .ecc-btn--danger:hover { --_bg: var(--ecc-danger-solid-hover); }
  .ecc-btn--tile:hover { --_bg: var(--ecc-btn-tile-hover); }
}
.ecc-btn--primary.is-hover { --_bg: var(--ecc-btn-hover); }
.ecc-btn--secondary.is-hover { --_bg: var(--ecc-wash); --_line: var(--ecc-ink); }
.ecc-btn--ghost.is-hover { text-decoration-color: var(--ecc-spark); text-decoration-thickness: 2px; }
.ecc-btn--danger.is-hover { --_bg: var(--ecc-danger-solid-hover); }
.ecc-btn--tile.is-hover { --_bg: var(--ecc-btn-tile-hover); }

/* pressed: the colour of the hover, held (the 1px drop is the shared rule above) */
.ecc-btn--primary:active, .ecc-btn--primary.is-pressed { --_bg: var(--ecc-btn-hover); }
.ecc-btn--secondary:active, .ecc-btn--secondary.is-pressed { --_bg: var(--ecc-wash-strong); --_line: var(--ecc-ink); }
.ecc-btn--ghost:active, .ecc-btn--ghost.is-pressed { --_bg: var(--ecc-wash-strong); text-decoration-color: var(--ecc-spark); text-decoration-thickness: 2px; }
.ecc-btn--danger:active, .ecc-btn--danger.is-pressed { --_bg: var(--ecc-danger-solid-hover); }
.ecc-btn--tile:active, .ecc-btn--tile.is-pressed { --_bg: var(--ecc-btn-tile-hover); }

.ecc-btn:disabled, .ecc-btn[aria-disabled="true"] {
  --_bg: var(--ecc-disabled-bg); --_fg: var(--ecc-disabled-fg); --_line: var(--ecc-disabled-line);
  cursor: not-allowed; text-decoration: none;
}
.ecc-btn--ghost:disabled, .ecc-btn--ghost[aria-disabled="true"] { --_bg: transparent; --_line: transparent; }
.ecc-btn--primary:disabled::before, .ecc-btn--primary[aria-disabled="true"]::before,
.ecc-btn--tile:disabled::before, .ecc-btn--tile[aria-disabled="true"]::before { background: currentColor; opacity: .55; }

/* loading: the pip gives way to three voxels lighting in turn; the label stays (aria-busy="true") */
.ecc-btn[aria-busy="true"] { cursor: progress; }
.ecc-btn--primary[aria-busy="true"]::before, .ecc-btn--tile[aria-busy="true"]::before { content: none; }
.ecc-loader { display: inline-grid; grid-auto-flow: column; gap: 3px; flex: none; }
.ecc-loader i { width: 5px; height: 5px; border-radius: 1px; background: var(--_loader, var(--ecc-spark)); opacity: .28; animation: ecc-vox var(--ecc-loader-loop) steps(1, end) infinite; }
.ecc-loader i:nth-child(2) { animation-delay: calc(var(--ecc-loader-loop) / -1.5); }
.ecc-loader i:nth-child(3) { animation-delay: calc(var(--ecc-loader-loop) / -3); }
.ecc-btn--primary .ecc-loader { --_loader: var(--ecc-btn-pip); }
.ecc-btn--danger .ecc-loader { --_loader: var(--ecc-on-danger); }
@keyframes ecc-vox { 0% { opacity: 1; } 34%, 100% { opacity: .28; } }

/* square icon button (search, account, bag, menu, close): a 24px icon in a 44px target. The name is its aria-label. */
.ecc-iconbtn {
  position: relative; flex: none; display: grid; place-items: center; width: var(--ecc-hit); height: var(--ecc-hit); padding: 0;
  border: 0; border-radius: var(--ecc-r-sm); background: transparent; color: var(--ecc-ink); cursor: pointer;
}
@media (hover: hover) and (pointer: fine) { .ecc-iconbtn:hover { background: var(--ecc-wash); } }
.ecc-iconbtn:active { background: var(--ecc-wash-strong); }

/* ================================================================ 5 · LINKS */
/* text link: underlined; the underline turns lime ink and thickens on hover */
.ecc-link {
  position: relative; color: var(--ecc-ink); border-radius: 2px;
  text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 5px;
  transition: text-decoration-color var(--ecc-d-fast) var(--ecc-ease-out);
}
.ecc-link::after { content: ""; position: absolute; inset: -14px -2px; } /* a 44px tap area that does not move the line */
@media (hover: hover) and (pointer: fine) { .ecc-link:hover { text-decoration-color: var(--ecc-spark); text-decoration-thickness: 2px; } }
.ecc-link.is-hover { text-decoration-color: var(--ecc-spark); text-decoration-thickness: 2px; }
/* standalone link line: mono, with the arrow-right icon (16px) after the words */
.ecc-linkline {
  display: inline-flex; align-items: center; gap: 8px; min-height: var(--ecc-hit); color: var(--ecc-ink); border-radius: 4px;
  text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 5px;
}
@media (hover: hover) and (pointer: fine) { .ecc-linkline:hover { text-decoration-color: var(--ecc-spark); text-decoration-thickness: 2px; } }

/* =============================================================== 6 · FIELDS */
.ecc-field { display: grid; gap: 8px; min-width: 0; }
/* a label speaks: Archivo in sentence case, 14px, ink ("Your name", "What can we help with?"). Never mono, never capitals,
   so a checkout form reads like a person asking. The same style names a group of choices (<legend class="ecc-label">). */
.ecc-label {
  display: block; color: var(--ecc-ink);
  font-family: var(--ecc-f-text); font-size: var(--ecc-t-small); font-weight: var(--ecc-fw-medium); font-stretch: var(--ecc-wdth-text);
  line-height: 1.4; letter-spacing: 0; text-transform: none;
}
.ecc-help { font-size: var(--ecc-t-small); line-height: 1.45; color: var(--ecc-ink-2); }
.ecc-error { display: flex; align-items: baseline; gap: 8px; font-size: var(--ecc-t-small); line-height: 1.45; font-weight: var(--ecc-fw-medium); color: var(--ecc-danger-fg); }
.ecc-error::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: var(--ecc-r-voxel); background: currentColor; }

/* fields are wells: white by day, the void at night */
.ecc-input {
  -webkit-appearance: none; appearance: none;
  display: block; width: 100%; min-height: 48px; padding: 12px 14px;
  border: 1px solid var(--ecc-control-line); border-radius: var(--ecc-r-sm);
  background: var(--ecc-field-bg); color: var(--ecc-ink);
  font-size: var(--ecc-t-body); line-height: 1.4;
  transition: border-color var(--ecc-d-fast) var(--ecc-ease-out), box-shadow var(--ecc-d-fast) var(--ecc-ease-out);
}
.ecc-input::placeholder { color: var(--ecc-ink-2); opacity: 1; }
textarea.ecc-input { min-height: 112px; resize: vertical; }
@media (hover: hover) and (pointer: fine) { .ecc-input:hover { border-color: var(--ecc-ink); } }
/* focus on a field: the ring sits on the border and the soft halo is added */
.ecc-input:focus-visible, .ecc-input.is-focus { outline: var(--ecc-focus-ring); outline-offset: -1px; border-color: var(--ecc-focus); box-shadow: var(--ecc-focus-halo); }
.ecc-input[aria-invalid="true"] { border-color: var(--ecc-danger-line); box-shadow: inset 0 0 0 1px var(--ecc-danger-line); }
.ecc-input[aria-invalid="true"]:focus-visible { box-shadow: var(--ecc-focus-halo); }
.ecc-input:disabled { background: var(--ecc-disabled-bg); color: var(--ecc-disabled-fg); border-color: var(--ecc-disabled-line); cursor: not-allowed; }
.ecc-input[type="search"]::-webkit-search-decoration,
.ecc-input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }

/* search: the 20px search icon sits inside the field, before the text */
.ecc-search { position: relative; }
.ecc-search .ecc-icon { position: absolute; left: 14px; top: 50%; margin-top: -10px; color: var(--ecc-ink); pointer-events: none; }
.ecc-search .ecc-input { padding-left: 44px; }

/* select: the wrapper holds the <select> and, after it, the 16px chevron-down icon */
.ecc-select { position: relative; }
.ecc-select select { padding-right: 44px; cursor: pointer; }
.ecc-select .ecc-icon { position: absolute; right: 14px; top: 50%; margin-top: -8px; color: var(--ecc-ink); pointer-events: none; }
.ecc-select select:disabled + .ecc-icon { color: var(--ecc-disabled-fg); }

/* ================================================ 7 · CHECK, RADIO, SWITCH */
/* the native input is the 44px tap target; the drawn box is its ::before, the mark its ::after */
.ecc-check, .ecc-switch { display: flex; align-items: flex-start; min-height: var(--ecc-hit); cursor: pointer; }
.ecc-check > span, .ecc-switch > span { padding: 10px 0; line-height: 1.5; }
.ecc-check input, .ecc-switch input {
  -webkit-appearance: none; appearance: none; flex: none; display: grid; place-items: center;
  width: var(--ecc-hit); height: var(--ecc-hit); margin: 0 2px 0 -11px; padding: 0; border: 0; border-radius: var(--ecc-r-sm);
  background: transparent; cursor: pointer;
}
.ecc-check input::before {
  content: ""; grid-area: 1 / 1; width: 22px; height: 22px; border-radius: 4px;
  background: var(--ecc-field-bg); box-shadow: inset 0 0 0 1.5px var(--ecc-control-line);
  transition: background-color var(--ecc-d-fast) var(--ecc-ease-out), box-shadow var(--ecc-d-fast) var(--ecc-ease-out);
}
/* the tick is five voxels */
.ecc-check input::after {
  content: ""; grid-area: 1 / 1; width: 3px; height: 3px; transform: translate(-6px, -4px);
  color: var(--ecc-btn-pip); box-shadow: 12px 0, 9px 3px, 0 6px, 6px 6px, 3px 9px; opacity: 0;
}
.ecc-check input:checked::before { background: var(--ecc-btn-bg); box-shadow: none; }
.ecc-check input:checked::after { opacity: 1; }
.ecc-check input[type="radio"]::before { border-radius: 50%; }
.ecc-check input[type="radio"]::after { width: 8px; height: 8px; border-radius: var(--ecc-r-voxel); background: var(--ecc-btn-pip); box-shadow: none; transform: none; }
@media (hover: hover) and (pointer: fine) {
  .ecc-check input:not(:checked):not(:disabled):hover::before, .ecc-switch input:not(:checked):not(:disabled):hover::before { box-shadow: inset 0 0 0 1.5px var(--ecc-ink); }
}
/* the ring goes round the drawn box, not round the 44px target */
.ecc-check input:focus-visible, .ecc-switch input:focus-visible, .ecc-check input.is-focus, .ecc-switch input.is-focus { outline: none; }
.ecc-check input:focus-visible::before, .ecc-switch input:focus-visible::before,
.ecc-check input.is-focus::before, .ecc-switch input.is-focus::before { outline: var(--ecc-focus-ring); outline-offset: 2px; }
.ecc-check input[aria-invalid="true"]:not(:checked)::before { box-shadow: inset 0 0 0 2px var(--ecc-danger-line); }
.ecc-check input:disabled, .ecc-switch input:disabled { cursor: not-allowed; }
.ecc-check input:disabled::before, .ecc-switch input:disabled::before { background: var(--ecc-disabled-bg); box-shadow: inset 0 0 0 1.5px var(--ecc-disabled-line); }
.ecc-check input:disabled ~ span, .ecc-switch input:disabled ~ span { color: var(--ecc-disabled-fg); }
.ecc-checks { display: grid; gap: 0; border: 0; margin: 0; padding: 0; min-width: 0; }
.ecc-checks legend { padding: 0; margin: 0 0 4px; } /* the legend is a label: <legend class="ecc-label"> */

/* switch: a square voxel thumb that moves in four pixel steps */
.ecc-switch { align-items: center; }
.ecc-switch > span { padding: 0; }
.ecc-switch input { width: 52px; margin: 0 6px 0 -6px; }
.ecc-switch input::before {
  content: ""; grid-area: 1 / 1; width: 40px; height: 22px; border-radius: 4px;
  background: var(--ecc-field-bg); box-shadow: inset 0 0 0 1.5px var(--ecc-control-line);
  transition: background-color var(--ecc-d-fast) var(--ecc-ease-out), box-shadow var(--ecc-d-fast) var(--ecc-ease-out);
}
.ecc-switch input::after {
  content: ""; grid-area: 1 / 1; width: 12px; height: 12px; border-radius: var(--ecc-r-voxel);
  background: var(--ecc-control-line); translate: -9px 0;
  transition: translate var(--ecc-d-base) var(--ecc-ease-pixel), background-color var(--ecc-d-fast) var(--ecc-ease-out);
}
.ecc-switch input:checked::before { background: var(--ecc-btn-bg); box-shadow: none; }
.ecc-switch input:checked::after { background: var(--ecc-btn-pip); translate: 9px 0; }

/* ===================================================== 8 · QUANTITY STEPPER */
.ecc-stepper {
  display: inline-grid; grid-template-columns: var(--ecc-hit) 52px var(--ecc-hit); align-items: stretch; justify-self: start; width: max-content; height: 48px;
  border: 1px solid var(--ecc-control-line); border-radius: var(--ecc-r-sm); background: var(--ecc-field-bg);
}
/* the buttons hold the 16px minus and plus icons */
.ecc-stepper__btn { display: grid; place-items: center; padding: 0; border: 0; border-radius: calc(var(--ecc-r-sm) - 1px); background: transparent; color: var(--ecc-ink); cursor: pointer; }
@media (hover: hover) and (pointer: fine) { .ecc-stepper__btn:not(:disabled):hover { background: var(--ecc-wash); } }
.ecc-stepper__btn:not(:disabled):active { background: var(--ecc-wash-strong); }
.ecc-stepper__btn:disabled { color: var(--ecc-disabled-fg); cursor: not-allowed; }
.ecc-stepper__input {
  -webkit-appearance: none; appearance: none; width: 100%; min-width: 0; padding: 0; border: 0; border-radius: 0;
  border-left: 1px solid var(--ecc-line-strong); border-right: 1px solid var(--ecc-line-strong);
  background: transparent; color: var(--ecc-ink); text-align: center;
  font-family: var(--ecc-f-mono); font-size: var(--ecc-t-body); font-weight: var(--ecc-fw-mono); font-stretch: var(--ecc-wdth-mono); font-variant-numeric: tabular-nums;
}
.ecc-stepper__btn:focus-visible, .ecc-stepper__input:focus-visible { outline-offset: -3px; }

/* ================================================================ 9 · CHIPS */
.ecc-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.ecc-chip {
  display: inline-flex; align-items: center; gap: 8px; min-height: var(--ecc-hit); padding: 0 16px;
  border: 1px solid var(--ecc-control-line); border-radius: var(--ecc-r-sm);
  background: var(--ecc-field-bg); color: var(--ecc-ink);
  font-size: .9375rem; font-weight: var(--ecc-fw-medium); line-height: 1; text-decoration: none; white-space: nowrap; cursor: pointer;
}
@media (hover: hover) and (pointer: fine) { .ecc-chip:not(.ecc-chip--removable):hover { border-color: var(--ecc-ink); } }
/* selected: ink fill and a lime pip by day; a lime line and a faint lime tint at night */
.ecc-chip[aria-pressed="true"], .ecc-chip.is-selected { background: var(--ecc-selected-bg); color: var(--ecc-selected-fg); border-color: var(--ecc-selected-line); }
.ecc-chip[aria-pressed="true"]::before, .ecc-chip.is-selected::before { content: ""; flex: none; width: 7px; height: 7px; border-radius: var(--ecc-r-voxel); background: var(--ecc-lime); }
/* removable (an applied filter): the label plus a 44px remove button that holds the 16px close icon */
.ecc-chip--removable { min-height: 46px; padding-right: 0; gap: 2px; cursor: default; }
.ecc-chip__x { flex: none; align-self: stretch; display: grid; place-items: center; width: var(--ecc-hit); min-height: var(--ecc-hit); padding: 0; border: 0; border-radius: calc(var(--ecc-r-sm) - 1px); background: transparent; color: inherit; cursor: pointer; }
@media (hover: hover) and (pointer: fine) { .ecc-chip__x:hover { background: var(--ecc-wash); } }
.ecc-chip__x:focus-visible { outline-offset: -3px; }

/* =============================================================== 10 · BADGES */
/* A badge NAMES: the category label behind a pip (.ecc-badge--cat), or a status behind a pip or a 16px icon
   ("By appointment", "Off-road only"). Mono capitals, a few words, not interactive.
   A badge never carries a promise. "Lease-to-own options", "Set up before you leave" and "Store pickup in Fullerton" are
   claims (11): they speak in Archivo and open an answer.
   A badge may wrap: a long label, or a translated one, takes a second line and never widens its card. */
.ecc-badges { display: flex; flex-wrap: wrap; gap: 8px; min-width: 0; }
.ecc-badge {
  display: inline-flex; align-items: center; gap: 7px; min-width: 0; max-width: 100%; min-height: 28px; padding: 4px 10px;
  border: 1px solid var(--ecc-line-strong); border-radius: 4px; color: var(--ecc-ink-2); overflow-wrap: anywhere;
}
.ecc-badge .ecc-pip { width: 6px; height: 6px; border-radius: 1px; }
.ecc-badge .ecc-icon { color: var(--ecc-ink); }
.ecc-badge--cat { padding-left: 0; border-color: transparent; }

/* ================================================== 11 · CLAIMS AND ANSWERS */
/* A claim is one of the store's promises, written as a sentence behind its icon: "Lease-to-own options",
   "Set up before you leave", "Store pickup in Fullerton". Archivo, sentence case, ink. Approved wording only.
     <ul class="ecc-claims"><li>
       <button class="ecc-claim" type="button" popovertarget="ID"> icon <span class="ecc-claim__text" id="ID-name">…</span></button>
       <div class="ecc-answer" id="ID" popover role="group" aria-labelledby="ID-name"> title, sentences, a link,
         <button class="ecc-iconbtn ecc-answer__close" type="button" popovertarget="ID" popovertargetaction="hide" aria-label="Close"> </div>
     </li></ul>
   .ecc-claim opens its answer: what it is, what it costs, who provides it, and a link to the whole page. The answer is a
   native popover, so there is no script: Escape or a tap outside closes it, focus returns to the claim, one is open at a time,
   and Tab goes from the claim into its answer. Several claims may open the same answer (popovertarget names its id).
   .ecc-claim--static is the same line without a button, for product cards: a card stays a small number of Tab stops.
   Wide screens: a small panel under its claim (CSS anchor positioning; a centred panel where the browser has none).
   640px and below: a bottom sheet with a Close button. No Popover API: the answers are plain text under their claims. */
.ecc-claims { display: grid; justify-items: start; gap: 0; min-width: 0; margin: 0; padding: 0; list-style: none; }
.ecc-claims > li { min-width: 0; max-width: 100%; }
.ecc-claims--row { display: flex; flex-wrap: wrap; gap: 0 28px; } /* a strip of claims side by side; it wraps */
.ecc-claim {
  display: inline-flex; align-items: center; gap: 10px; min-width: 0; max-width: 100%; min-height: var(--ecc-hit); margin: 0; padding: 0;
  border: 0; border-radius: 4px; background: transparent; color: var(--ecc-ink); text-align: left; cursor: pointer;
  font-family: var(--ecc-f-text); font-size: .9375rem; font-weight: var(--ecc-fw-medium); font-stretch: var(--ecc-wdth-text);
  line-height: 1.35; letter-spacing: 0; text-transform: none; -webkit-tap-highlight-color: transparent;
}
.ecc-claim > .ecc-icon { color: var(--ecc-ink); }
/* the underline says "this opens": it turns lime ink and thickens on hover and while the answer is open, like a link */
.ecc-claim__text {
  min-width: 0; overflow-wrap: anywhere;
  text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 5px;
  transition: text-decoration-color var(--ecc-d-fast) var(--ecc-ease-out);
}
@media (hover: hover) and (pointer: fine) { .ecc-claim:hover .ecc-claim__text { text-decoration-color: var(--ecc-spark); text-decoration-thickness: 2px; } }
.ecc-claim.is-hover .ecc-claim__text, .ecc-claim.is-open .ecc-claim__text { text-decoration-color: var(--ecc-spark); text-decoration-thickness: 2px; }
.ecc-claim:has(+ .ecc-answer:popover-open) .ecc-claim__text { text-decoration-color: var(--ecc-spark); text-decoration-thickness: 2px; }
/* static: a line, not a control. It wraps on a narrow card and never forces a width. */
.ecc-claim--static { display: flex; align-items: flex-start; gap: 8px; min-height: 0; padding: 3px 0; cursor: auto; }
.ecc-claim--static > .ecc-icon { margin-top: 2px; } /* a 16px icon beside the first line (20px) */
.ecc-claim--static .ecc-claim__text, .ecc-claim--static:hover .ecc-claim__text { text-decoration: none; }

/* The answer, first as plain text: this is all a browser without the Popover API shows, under its claim. */
.ecc-answer { max-width: 30em; margin: 0 0 12px; padding: 0 0 0 30px; color: var(--ecc-ink); font-size: var(--ecc-t-body); line-height: 1.5; }
.ecc-answer p + p { margin-top: 8px; }
.ecc-answer__lead { font-weight: var(--ecc-fw-strong); } /* the sentence that must not be missed: the cost */
.ecc-answer__title, .ecc-answer__close { display: none; }
.ecc-answer .ecc-linkline { margin-top: 2px; }

/* No Popover API: a claim opens nothing, and its answer is already on the page under it. So it stops looking like a control. */
@supports not selector(:popover-open) {
  .ecc-claim { cursor: auto; }
  .ecc-claim .ecc-claim__text, .ecc-claim:hover .ecc-claim__text { text-decoration: none; }
}
@supports selector(:popover-open) {
  /* The panel: a light surface inside a clear line. On wide screens nothing dims the page behind it, so the line is the
     control line (8.07:1 on a tile by day), not the hairline of the other overlays. */
  .ecc-answer {
    width: min(380px, calc(100vw - 32px)); max-width: none; max-height: calc(100dvh - 32px); margin: 0; padding: 18px 8px 12px 20px;
    border: 0; border-radius: var(--ecc-r); background: var(--ecc-surface); box-shadow: 0 0 0 1px var(--ecc-control-line); overflow: auto;
  }
  /* open: the words in one column, the 44px Close button beside the first line. .is-open shows it in the style guide,
     in the flow of the page, where it is never wider than the place it sits in. */
  .ecc-answer.is-open, .ecc-answer:popover-open { display: grid; grid-template-columns: minmax(0, 1fr) var(--ecc-hit); column-gap: 4px; align-content: start; }
  .ecc-answer.is-open { max-width: 100%; }
  .ecc-answer > * { grid-column: 1; }
  .ecc-answer__close { display: grid; grid-column: 2; grid-row: 1 / span 5; align-self: start; margin-top: -10px; }
  /* the title names the answer (a mono label behind a pip). Only the sheet shows it: the sheet opens away from its claim. */
  .ecc-answer__title { align-items: center; gap: 8px; min-height: var(--ecc-hit); margin: 0; color: var(--ecc-ink-2); }

  /* as a popover: it rises --ecc-rise into place. Centred in the window where there is no anchor positioning. */
  .ecc-answer[popover] {
    margin: auto; opacity: 0; translate: 0 var(--ecc-rise);
    transition: opacity var(--ecc-d-fast) var(--ecc-ease-out), translate var(--ecc-d-fast) var(--ecc-ease-out),
      overlay var(--ecc-d-fast) allow-discrete, display var(--ecc-d-fast) allow-discrete;
  }
  .ecc-answer[popover]:popover-open { opacity: 1; translate: none; }
  @starting-style { .ecc-answer[popover]:popover-open { opacity: 0; translate: 0 var(--ecc-rise); } }
  .ecc-answer[popover]::backdrop { background: transparent; }

  /* the sheet, as a forced sample for the style guide (.is-open.is-sheet): the look only, the page places it */
  .ecc-answer.is-sheet { width: auto; padding: 8px 8px 16px 20px; border-radius: var(--ecc-r) var(--ecc-r) 0 0; }
  .ecc-answer.is-sheet .ecc-answer__title { display: flex; }
  .ecc-answer.is-sheet .ecc-answer__close { margin-top: 0; }
}
/* Under its claim: the claim that opened a popover is its anchor. With no room below it opens above; with no room to the
   right it lines up with the claim's right edge. */
@supports selector(:popover-open) and (position-area: bottom) {
  .ecc-answer[popover] { inset: auto; margin: 6px 0; position-area: bottom span-right; position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline; }
}
/* no anchor positioning: the panel opens in the centre of the window, away from its claim, so the page behind is dimmed */
@supports selector(:popover-open) and (not (position-area: bottom)) {
  .ecc-answer[popover]:popover-open::backdrop { background: var(--ecc-scrim); }
}
/* 640px and below: a bottom sheet. Full width, clear of the phone's home bar, with its title and the Close button on the
   first row. The page behind is dimmed, and the sheet slides up (it just appears when motion is reduced, see 24).
   env(safe-area-inset-bottom) is 0 until the page's viewport meta says viewport-fit=cover: the theme's header sets it. */
@media (max-width: 640px) {
  @supports selector(:popover-open) {
    .ecc-answer[popover] {
      inset: auto 0 0; position-area: none; width: auto; max-height: 86dvh; margin: 0;
      padding: 8px 8px calc(16px + env(safe-area-inset-bottom)) 20px; border-radius: var(--ecc-r) var(--ecc-r) 0 0;
      opacity: 1; translate: 0 100%; transition-duration: var(--ecc-d-base);
    }
    .ecc-answer[popover]:popover-open { translate: none; }
    @starting-style { .ecc-answer[popover]:popover-open { opacity: 1; translate: 0 100%; } }
    .ecc-answer[popover] .ecc-answer__title { display: flex; }
    .ecc-answer[popover] .ecc-answer__close { margin-top: 0; }
    .ecc-answer[popover]::backdrop { transition: background-color var(--ecc-d-base) linear, overlay var(--ecc-d-base) allow-discrete, display var(--ecc-d-base) allow-discrete; }
    .ecc-answer[popover]:popover-open::backdrop { background: var(--ecc-scrim); }
    @starting-style { .ecc-answer[popover]:popover-open::backdrop { background: transparent; } }
  }
}

/* ========================================================= 12 · PRODUCT CARD */
/* direction B's tile: a lit stage (the pixel kit's .pk-stage), the name, its claims as static lines, two actions.
   No price slot yet.
   The name is always two lines high: a short name leaves the second line empty, a long one ends in an ellipsis, so every
   card in a row has the same height whatever the catalogue holds (names reach 84 characters). The full name is the link's
   text, and it is shown whole on the product page.
   The dot-matrix number (.ecc-card__num) numbers a real, curated sequence: a featured row of three, a rotating tile.
   Never in a grid that can be sorted or filtered: there it would number nothing, and read as a rank. */
.ecc-card {
  display: flex; flex-direction: column; min-width: 0;
  border-radius: var(--ecc-r); background: var(--ecc-surface); color: var(--ecc-ink);
  box-shadow: var(--ecc-elev-module); transition: box-shadow var(--ecc-d-fast) var(--ecc-ease-out);
}
@media (hover: hover) and (pointer: fine) { .ecc-card:hover { box-shadow: var(--ecc-elev-raised); } }
.ecc-card:focus-within { box-shadow: var(--ecc-elev-raised); }
.ecc-card .pk-stage { margin: 8px 8px 0; height: clamp(260px, 24vw, 340px); }
.ecc-card__label { position: absolute; left: 16px; top: 14px; z-index: 3; display: flex; align-items: center; gap: 8px; max-width: calc(100% - 96px); margin: 0; color: var(--ecc-ink-2); } /* leaves the corner to the number */
.ecc-card__num { position: absolute; right: 14px; top: 10px; z-index: 3; font-size: 24px; font-weight: 900; color: var(--ecc-ink); } /* the stage is light by day: 24px, 900. A curated sequence only (see above) */
.ecc-card__body { display: flex; flex-direction: column; flex: 1; gap: 14px; min-width: 0; padding: 18px 20px 20px; }
/* the name: a box two lines high (2 x the 1.2 line height of .ecc-h3), always. One line sits in its middle. The link is
   clamped to two lines; its ::after stretches over the whole box, so the tap target is 48px or more whatever the length */
.ecc-card__name { position: relative; display: flex; align-items: center; height: 2.4em; }
.ecc-card__name a {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
  min-width: 0; overflow-wrap: anywhere; color: inherit; text-decoration: none; border-radius: 4px;
}
.ecc-card__name a::after { content: ""; position: absolute; inset: 0; }
@media (hover: hover) and (pointer: fine) { .ecc-card__name a:hover { text-decoration: underline; text-decoration-color: var(--ecc-spark); text-decoration-thickness: 2px; text-underline-offset: 3px; } }
.ecc-card__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-width: 0; margin-top: auto; }
/* a long or a translated label wraps inside its button; it never pushes the card wider */
.ecc-card__actions .ecc-btn { max-width: 100%; padding-block: 10px; white-space: normal; line-height: 1.25; text-align: left; }

/* =========================================================== 13 · SPEC TABLE */
.ecc-spec > div { display: grid; grid-template-columns: 112px minmax(0, 1fr); gap: 12px; padding: 12px 0; border-top: 1px solid var(--ecc-line); }
.ecc-spec > div:last-child { border-bottom: 1px solid var(--ecc-line); }
.ecc-spec dt { padding-top: 3px; color: var(--ecc-ink-2); }

/* =============================================================== 14 · ALERTS */
.ecc-alert {
  --_fg: var(--ecc-info-fg); --_bg: var(--ecc-info-bg); --_line: var(--ecc-info-line);
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 2px 12px; align-items: start;
  padding: 14px 16px; border: 1px solid var(--_line); border-radius: var(--ecc-r-sm);
  background: var(--_bg); color: var(--ecc-ink);
}
.ecc-alert::before { content: ""; width: 8px; height: 8px; margin-top: 5px; border-radius: var(--ecc-r-voxel); background: var(--_fg); }
.ecc-alert__title { color: var(--_fg); }
.ecc-alert__text { grid-column: 2; }
.ecc-alert--success { --_fg: var(--ecc-success-fg); --_bg: var(--ecc-success-bg); --_line: var(--ecc-success-line); }
.ecc-alert--warning { --_fg: var(--ecc-warning-fg); --_bg: var(--ecc-warning-bg); --_line: var(--ecc-warning-line); }
.ecc-alert--danger { --_fg: var(--ecc-danger-fg); --_bg: var(--ecc-danger-bg); --_line: var(--ecc-danger-line); }

/* ========================================================== 15 · BREADCRUMBS */
.ecc-crumbs { display: flex; flex-wrap: wrap; align-items: center; margin: 0; padding: 0; list-style: none; }
.ecc-crumbs li { display: flex; align-items: center; }
.ecc-crumbs li + li::before { content: "/"; padding: 0 2px; color: var(--ecc-ink-2); }
.ecc-crumbs a, .ecc-crumbs [aria-current] { display: inline-flex; align-items: center; min-height: var(--ecc-hit); min-width: var(--ecc-hit); justify-content: center; padding: 0 8px; border-radius: 4px; }
.ecc-crumbs a { color: var(--ecc-ink-2); text-decoration: none; }
@media (hover: hover) and (pointer: fine) { .ecc-crumbs a:hover { color: var(--ecc-ink); text-decoration: underline; text-decoration-color: var(--ecc-spark); text-decoration-thickness: 2px; text-underline-offset: 5px; } }
.ecc-crumbs [aria-current] { color: var(--ecc-ink); }

/* ========================================================== 16 · PAGINATION */
.ecc-pager { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin: 0; padding: 0; list-style: none; }
.ecc-pager a, .ecc-pager span {
  display: inline-flex; align-items: center; justify-content: center; min-width: var(--ecc-hit); min-height: var(--ecc-hit); padding: 0 12px;
  border: 1px solid transparent; border-radius: var(--ecc-r-sm); color: var(--ecc-ink); text-decoration: none;
}
@media (hover: hover) and (pointer: fine) { .ecc-pager a:not([aria-current]):hover { background: var(--ecc-wash); } }
.ecc-pager [aria-current] { background: var(--ecc-selected-bg); color: var(--ecc-selected-fg); border-color: var(--ecc-selected-line); }
.ecc-pager .ecc-pager__step { gap: 6px; border-color: var(--ecc-control-line); padding: 0 14px; } /* Previous and Next: the word and a 16px chevron */
.ecc-pager [aria-disabled="true"] { border-color: var(--ecc-disabled-line); background: var(--ecc-disabled-bg); color: var(--ecc-disabled-fg); }
.ecc-pager .ecc-pager__gap { color: var(--ecc-ink-2); min-width: 28px; padding: 0; }
@media (max-width: 480px) { /* on a phone the row keeps to one line: Previous, three pages, Next */
  .ecc-pager { gap: 2px; }
  .ecc-pager .ecc-pager__step { gap: 2px; padding: 0 8px; }
}

/* ================================================================= 17 · TABS */
.ecc-tabs__list { display: flex; gap: 4px; overflow-x: auto; scrollbar-width: none; border-bottom: 1px solid var(--ecc-line-strong); }
.ecc-tabs__list::-webkit-scrollbar { display: none; }
.ecc-tab {
  position: relative; flex: none; min-height: 48px; padding: 0 14px; border: 0; border-radius: 4px 4px 0 0;
  background: transparent; color: var(--ecc-ink-2); cursor: pointer; white-space: nowrap;
}
/* the selected tab carries the lime current */
.ecc-tab::after {
  content: ""; position: absolute; left: 14px; right: 14px; bottom: 0; height: 2px; background: var(--ecc-spark);
  scale: 0 1; transform-origin: left center; transition: scale var(--ecc-d-base) var(--ecc-ease-current);
}
.ecc-tab[aria-selected="true"] { color: var(--ecc-ink); }
.ecc-tab[aria-selected="true"]::after { scale: 1 1; }
@media (hover: hover) and (pointer: fine) { .ecc-tab:hover { color: var(--ecc-ink); background: var(--ecc-wash); } }
.ecc-tab:focus-visible { outline-offset: -3px; }
.ecc-tabs__panel { padding-top: 20px; }
.ecc-tabs__panel:focus-visible { outline-offset: 6px; border-radius: 4px; }

/* ============================================================ 18 · ACCORDION */
.ecc-acc { border-top: 1px solid var(--ecc-line-strong); }
.ecc-acc:last-of-type { border-bottom: 1px solid var(--ecc-line-strong); }
.ecc-acc > summary {
  display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 56px; padding: 8px 2px;
  list-style: none; cursor: pointer; font-weight: var(--ecc-fw-strong); border-radius: 4px;
}
.ecc-acc > summary::-webkit-details-marker { display: none; }
/* plus becomes minus */
.ecc-acc > summary::after {
  content: ""; flex: none; width: 12px; height: 12px; margin-right: 6px;
  background: linear-gradient(currentColor, currentColor) center / 12px 2px no-repeat, linear-gradient(currentColor, currentColor) center / 2px 12px no-repeat;
  transition: background-size var(--ecc-d-fast) var(--ecc-ease-out);
}
.ecc-acc[open] > summary::after { background-size: 12px 2px, 2px 0; }
.ecc-acc__body { max-width: 30em; padding: 0 2px 18px; color: var(--ecc-ink-2); } /* text blocks are sized in em, never in ch (typography.md 7) */
.ecc-acc__body p + p { margin-top: 8px; }
.ecc-acc__body .ecc-answer__lead { color: var(--ecc-ink); } /* the cost sentence of an answer (11) stays ink */

/* ============================================================== 19 · TOOLTIP */
/* shows on hover and on keyboard focus, stays while hovered, closes with Escape (.is-dismissed) */
.ecc-tip { position: relative; display: inline-flex; }
.ecc-tip__btn {
  display: grid; place-items: center; width: var(--ecc-hit); height: var(--ecc-hit); padding: 0;
  border: 0; border-radius: var(--ecc-r-sm); background: transparent; color: var(--ecc-ink); cursor: help;
} /* the trigger holds the 24px info icon */
.ecc-tip__bubble {
  position: absolute; right: 0; bottom: calc(100% + 4px); z-index: var(--ecc-z-overlay);
  width: max-content; max-width: min(264px, calc(100vw - 48px)); padding: 10px 12px;
  border-radius: var(--ecc-r-sm); background: var(--ecc-panel-2); color: var(--ecc-on-panel); box-shadow: var(--ecc-elev-overlay);
  font-size: var(--ecc-t-small); line-height: 1.45; text-align: left;
  opacity: 0; visibility: hidden; translate: 0 var(--ecc-rise);
  transition: opacity var(--ecc-d-fast) var(--ecc-ease-out), translate var(--ecc-d-fast) var(--ecc-ease-out), visibility 0s linear var(--ecc-d-fast);
}
.ecc-tip__bubble::after { content: ""; position: absolute; right: 18px; bottom: -4px; width: 8px; height: 8px; background: inherit; transform: rotate(45deg); }
.ecc-tip:hover .ecc-tip__bubble, .ecc-tip:focus-within .ecc-tip__bubble, .ecc-tip.is-open .ecc-tip__bubble { opacity: 1; visibility: visible; translate: none; transition-delay: 0s; }
.ecc-tip.is-dismissed .ecc-tip__bubble { opacity: 0; visibility: hidden; }

/* ================================================================ 20 · TOAST */
/* a short confirmation on the graphite panel (pair with .ecc-ctx-panel). The region is fixed; a toast alone is inline. */
.ecc-toasts { position: fixed; right: var(--ecc-gutter); bottom: var(--ecc-gutter); z-index: var(--ecc-z-toast); display: grid; gap: 8px; width: min(420px, calc(100vw - 32px)); pointer-events: none; }
.ecc-toasts > * { pointer-events: auto; }
.ecc-toast {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 0 12px; width: min(420px, 100%);
  padding: 4px 4px 4px 16px; border-radius: var(--ecc-r); background: var(--ecc-panel-2); color: var(--ecc-ink); box-shadow: var(--ecc-elev-overlay);
}
.ecc-toast::before { content: ""; width: 8px; height: 8px; border-radius: var(--ecc-r-voxel); background: var(--ecc-spark); }
.ecc-toast__text { padding: 10px 0; line-height: 1.4; }
.ecc-toast__text strong { display: block; font-weight: var(--ecc-fw-strong); }
.ecc-toast__text span { color: var(--ecc-ink-2); }
.ecc-toast__actions { display: flex; align-items: center; gap: 4px; }
.ecc-toast.is-in { animation: ecc-toast-in var(--ecc-d-base) var(--ecc-ease-out); }
@keyframes ecc-toast-in { from { opacity: 0; translate: 0 var(--ecc-rise); } }

/* ============================================================= 21 · SKELETON */
/* a calm voxel shimmer: quiet blocks, and a band of voxels one tone stronger that steps across them.
   Neutral on purpose: a skeleton can cover a large area, and lime stays a spark. */
.ecc-skel { position: relative; display: block; overflow: hidden; min-height: 12px; border-radius: var(--ecc-r-voxel); background: var(--ecc-wash-strong); }
.ecc-skel::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, var(--ecc-wash-strong) 35%, var(--ecc-wash-strong) 65%, transparent) no-repeat -160px 0 / 160px 100%;
  -webkit-mask: linear-gradient(90deg, #000 6px, transparent 6px) 0 0 / 8px 8px, linear-gradient(#000 6px, transparent 6px) 0 0 / 8px 8px;
  -webkit-mask-composite: source-in;
  mask: linear-gradient(90deg, #000 6px, transparent 6px) 0 0 / 8px 8px, linear-gradient(#000 6px, transparent 6px) 0 0 / 8px 8px;
  mask-composite: intersect;
  animation: ecc-shimmer var(--ecc-shimmer-loop) steps(18, end) infinite;
}
.ecc-skel--line { height: 14px; }
.ecc-skel--title { height: 22px; }
.ecc-skel--pill { height: 28px; width: 148px; border-radius: 4px; }
.ecc-skel--btn { height: 48px; width: 150px; border-radius: var(--ecc-r-sm); }
.ecc-skel--stage { border-radius: var(--ecc-r-sm); }
@keyframes ecc-shimmer { to { background-position: calc(100% + 160px) 0; } }

/* ========================================================== 22 · EMPTY STATE */
.ecc-empty { display: grid; justify-items: center; gap: 12px; padding: 40px 20px; text-align: center; }
.ecc-empty p { max-width: 25em; color: var(--ecc-ink-2); }
/* nine voxels, one lit: an empty slot */
.ecc-empty__art { display: grid; grid-template-columns: repeat(3, 12px); gap: 5px; margin-bottom: 8px; }
.ecc-empty__art i { width: 12px; height: 12px; border-radius: var(--ecc-r-voxel); background: var(--ecc-wash-strong); }
.ecc-empty__art i:nth-child(5) { background: var(--ecc-lime); box-shadow: var(--ecc-lime-edge); }
.ecc-empty__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 8px; }

/* =============================================================== 23 · DRAWER */
/* shell of a side drawer (cart, filters, menu). In the theme: .ecc-drawer--fixed over .ecc-scrim. */
.ecc-scrim { position: fixed; inset: 0; z-index: var(--ecc-z-overlay); background: var(--ecc-scrim); }
.ecc-drawer { display: flex; flex-direction: column; width: min(420px, 100%); height: 100%; background: var(--ecc-surface); color: var(--ecc-ink); box-shadow: var(--ecc-elev-overlay); }
.ecc-drawer--fixed { position: fixed; top: 0; right: 0; bottom: 0; z-index: var(--ecc-z-modal); }
.ecc-drawer__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 10px 10px 20px; border-bottom: 1px solid var(--ecc-line-strong); }
.ecc-drawer__title { display: flex; align-items: baseline; gap: 12px; }
.ecc-drawer__body { flex: 1; min-height: 0; overflow: auto; padding: 0 20px; }
.ecc-drawer__foot { display: grid; gap: 12px; padding: 16px 20px 20px; border-top: 1px solid var(--ecc-line-strong); }
.ecc-drawer__facts { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; color: var(--ecc-ink-2); }
.ecc-drawer__facts li { display: flex; align-items: center; gap: 8px; }
.ecc-drawer__facts .ecc-icon { color: var(--ecc-ink); }
.ecc-cartline { display: grid; grid-template-columns: 88px minmax(0, 1fr); gap: 14px; padding: 16px 0; border-bottom: 1px solid var(--ecc-line); }
.ecc-cartline:last-child { border-bottom: 0; }
/* a small stage built straight from the stage tokens */
.ecc-cartline__thumb { display: flex; align-items: center; justify-content: center; height: 88px; border-radius: var(--ecc-r-sm); background: var(--ecc-stage-bg); overflow: hidden; }
.ecc-cartline__thumb img { max-width: 76%; max-height: 76%; width: auto; height: auto; object-fit: contain; filter: var(--ecc-stage-img-filter); }
.ecc-cartline__name { font-weight: var(--ecc-fw-strong); line-height: 1.3; overflow-wrap: anywhere; }
.ecc-cartline__meta { margin-top: 2px; color: var(--ecc-ink-2); }
.ecc-cartline__row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; margin-top: 10px; }

/* ======================================================= 24 · REDUCED MOTION */
@media (prefers-reduced-motion: reduce) {
  .ecc-loader i, .ecc-skel::after, .ecc-toast.is-in { animation: none; }
  .ecc-loader i:first-child { opacity: 1; }
  .ecc-skel::after { background-position: 30% 0; }
  .ecc-btn, .ecc-iconbtn, .ecc-chip, .ecc-chip__x, .ecc-stepper__btn, .ecc-tab, .ecc-pager a, .ecc-tip__btn,
  .ecc-link, .ecc-input, .ecc-check input::before, .ecc-switch input::before, .ecc-switch input::after, .ecc-tab::after,
  .ecc-tip__bubble, .ecc-card, .ecc-acc > summary::after, .ecc-claim, .ecc-claim__text { transition: none; }
  /* an answer appears in place: no rise, no slide of the sheet, no fade of the page behind it */
  .ecc-answer[popover], .ecc-answer[popover]::backdrop { transition: none; }
}

/* ============================================ 25 · FORCED COLOURS (high contrast) */
/* Windows High Contrast, and any forced-colours mode, repaints the page in the visitor's own palette and drops every
   background colour, shadow and gradient. Whatever this file draws with one of those would vanish, and the state it
   carries with it. So each is drawn again with a border, in system colours: CanvasText for an edge, Highlight for "on"
   (checked, selected, current), GrayText for inactive. Text and icons need nothing: the browser repaints them. */
@media (forced-colors: active) {
  /* 7 · the drawn box of a checkbox, a radio and a switch: a 2px edge; filled with Highlight when it is on */
  .ecc-check input::before, .ecc-switch input::before { background: Canvas; border: 2px solid CanvasText; }
  .ecc-check input:checked::before, .ecc-switch input:checked::before { background: Highlight; border-color: Highlight; }
  .ecc-check input::after { forced-color-adjust: none; color: HighlightText; } /* the five-voxel tick is drawn with shadows: keep them */
  .ecc-check input[type="radio"]::after { background: HighlightText; }
  .ecc-switch input::after { background: CanvasText; }
  .ecc-switch input:checked::after { background: HighlightText; }
  .ecc-check input:disabled::before, .ecc-switch input:disabled::before { background: Canvas; border-color: GrayText; }
  .ecc-check input:disabled:checked::before, .ecc-switch input:disabled:checked::before { background: GrayText; }
  .ecc-switch input:disabled::after { background: GrayText; }
  .ecc-check input:disabled ~ span, .ecc-switch input:disabled ~ span { color: GrayText; }
  .ecc-input[aria-invalid="true"] { border-width: 2px; }

  /* 9, 16, 17 · selected chip, current page, selected tab: a 2px Highlight line where the fill or the lime line was */
  .ecc-chip[aria-pressed="true"], .ecc-chip.is-selected { padding-left: 15px; padding-right: 15px; border: 2px solid Highlight; }
  .ecc-chip[aria-pressed="true"]::before, .ecc-chip.is-selected::before { background: Highlight; }
  .ecc-pager [aria-current] { padding: 0 11px; border: 2px solid Highlight; }
  .ecc-tab { border: 2px solid ButtonFace; }
  .ecc-tab[aria-selected="true"] { border-color: Highlight; }

  /* 4 · every button keeps an edge (its transparent border is repainted); the pip and the busy voxels are drawn again */
  .ecc-btn { border-color: ButtonBorder; }
  .ecc-btn:disabled, .ecc-btn[aria-disabled="true"] { border-color: GrayText; color: GrayText; }
  .ecc-btn--primary::before, .ecc-btn--tile::before, .ecc-loader i { background: ButtonText; }
  .ecc-btn:disabled::before, .ecc-btn[aria-disabled="true"]::before { background: GrayText; }

  /* 11 · a claim is a button: it gets an edge. Its answer, and every other layer or tile, gets one too */
  .ecc-claim:not(.ecc-claim--static) { padding: 0 10px; border: 1px solid ButtonBorder; }
  .ecc-answer { border: 2px solid CanvasText; }
  .ecc-tip__bubble, .ecc-toast, .ecc-drawer, .ecc-module, .ecc-card { border: 1px solid CanvasText; }
  .ecc-tip__bubble::after { display: none; } /* the arrow was a filled square */
  .ecc-skel { border: 1px solid GrayText; }
  /* 18 · the plus of the accordion was two gradients: a chevron drawn with borders takes its place */
  .ecc-acc > summary::after { width: 8px; height: 8px; margin-right: 8px; border: solid CanvasText; border-width: 0 2px 2px 0; rotate: 45deg; }
  .ecc-acc[open] > summary::after { rotate: -135deg; }
}
