/* Base styles + aurora background + shared components (public and admin). See docs/DESIGN.md. */
/* No @font-face: public/fonts/ is empty, so declaring one cost a 404 on every first page load (audit).
   --font still lists "Inter" first, so a locally installed Inter is used. To ship the webfont, drop
   inter-var.woff2 into public/fonts/ and restore:
   @font-face{font-family:"Inter";font-style:normal;font-weight:100 900;font-display:swap;src:url("/static/fonts/inter-var.woff2") format("woff2")} */

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{margin:0;min-height:100vh;font-family:var(--font);font-size:var(--fs-base);line-height:var(--lh);color:var(--text);
  background:var(--bg-0) radial-gradient(120% 90% at 50% -10%,var(--bg-2),var(--bg-0)) fixed;-webkit-font-smoothing:antialiased}
img,svg{max-width:100%;display:block}
/* The logo <picture> must not become an inline box with a baseline gap; the error shell has no site.css, so the
   wordmark's size lives here too (ADR-036). */
.logo picture,.bare-logo picture{display:block;flex:none}
.bare-logo{display:inline-block;margin-bottom:var(--s-4)}.bare-logo .logo__img{height:30px;width:auto;max-width:none}
a{color:var(--text-link);text-decoration:none}
a:hover{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px}
h1,h2,h3,h4{margin:0 0 var(--s-3);line-height:var(--lh-tight);font-weight:700;letter-spacing:-.01em}
h1{font-size:var(--fs-2xl)} h2{font-size:var(--fs-xl)} h3{font-size:var(--fs-lg)} h4{font-size:var(--fs-md)}
p{margin:0 0 var(--s-4)}
small,.muted{color:var(--text-muted)}
.text-2{color:var(--text-2)}
code,kbd,.mono{font-family:var(--font-mono);font-size:.92em}
.num,td.num,th.num{font-variant-numeric:tabular-nums;text-align:right;white-space:nowrap}
:focus-visible{outline:none;box-shadow:var(--focus-ring);border-radius:var(--r-sm)}
::selection{background:var(--selection)}
.visually-hidden{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
[hidden]{display:none!important}
/* Keeps the last word and its arrow together ("we quote it →"). svg is display:block above, which would break the
   line inside the span anyway (visual 9). */
.nowrap{white-space:nowrap}.nowrap>svg{display:inline-block;vertical-align:-2px}
hr{border:0;border-top:1px solid var(--divider);margin:var(--s-5) 0}

/* ─── Aurora ─────────────────────────────────────────── */
.aurora{position:fixed;inset:-20%;z-index:-1;pointer-events:none;contain:strict;overflow:hidden}
.aurora span{position:absolute;border-radius:50%;mix-blend-mode:screen;filter:blur(70px);will-change:transform;opacity:.55}
.aurora .a1{width:80vmax;height:80vmax;left:-10%;top:-20%;background:radial-gradient(closest-side,var(--aurora-3) 0%,transparent 70%);animation:drift1 46s linear infinite alternate}
.aurora .a2{width:70vmax;height:70vmax;right:-15%;top:-10%;background:radial-gradient(closest-side,var(--aurora-5) 0%,transparent 70%);animation:drift2 58s linear infinite alternate;opacity:.5}
.aurora .a3{width:90vmax;height:60vmax;left:20%;bottom:-30%;background:radial-gradient(closest-side,var(--aurora-4) 0%,transparent 70%);animation:drift3 72s linear infinite alternate;opacity:.45}
.aurora .ribbon{position:absolute;inset:-40%;background:var(--ribbon);opacity:.08;filter:blur(40px);animation:spin 130s linear infinite;will-change:transform}
.aurora .grain{position:absolute;inset:0;opacity:.035;background:repeating-linear-gradient(0deg,rgba(255,255,255,.4) 0 1px,transparent 1px 3px)}
@keyframes drift1{from{transform:translate3d(0,0,0) scale(1)}to{transform:translate3d(9vw,7vh,0) scale(1.15)}}
@keyframes drift2{from{transform:translate3d(0,0,0) scale(1.05)}to{transform:translate3d(-8vw,10vh,0) scale(.95)}}
@keyframes drift3{from{transform:translate3d(0,0,0) scale(1)}to{transform:translate3d(6vw,-9vh,0) scale(1.2)}}
@keyframes spin{to{transform:rotate(1turn)}}
.aurora--calm span{animation:none;opacity:.32}.aurora--calm .ribbon{animation:none;opacity:.05}
@media (max-width:767px){.aurora span{filter:none;opacity:.3}.aurora .ribbon{display:none}}
@media (prefers-reduced-motion:reduce){.aurora *{animation:none!important}html{scroll-behavior:auto}}

/* ─── Layout ─────────────────────────────────────────── */
.container{width:100%;max-width:var(--container);margin:0 auto;padding-inline:var(--s-4)}
.container--narrow{max-width:var(--container-narrow)}
@media (min-width:768px){.container{padding-inline:var(--s-5)}}
.stack>*+*{margin-top:var(--s-4)}
.row{display:flex;flex-wrap:wrap;gap:var(--s-3);align-items:center}
.row--between{justify-content:space-between}
.grid{display:grid;gap:var(--s-4)}
.grid--2{grid-template-columns:repeat(auto-fit,minmax(min(100%,280px),1fr))}
.grid--3{grid-template-columns:repeat(auto-fit,minmax(min(100%,240px),1fr))}
.grid--4{grid-template-columns:repeat(auto-fit,minmax(min(100%,200px),1fr))}
.section{padding-block:var(--s-7)}
.section--tight{padding-block:var(--s-5)}
.band{position:relative;border-block:1px solid var(--divider);background:var(--grad-aurora-soft)}

/* ─── Surfaces ───────────────────────────────────────── */
.card{background:var(--surface-1);border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--shadow-2),inset 0 1px 0 var(--highlight-top);padding:var(--s-5)}
.card--solid{background:var(--surface-solid)}
.card--hover:hover{background:var(--surface-2);border-color:var(--border-accent)}
.card--tight{padding:var(--s-4)}
.card h2:first-child,.card h3:first-child{margin-top:0}
.glass{background:var(--surface-1);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px)}

/* ─── Buttons ────────────────────────────────────────── */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--s-2);min-height:44px;padding:0 var(--s-5);border-radius:var(--r-pill);
  font:inherit;font-weight:600;font-size:var(--fs-base);line-height:1;cursor:pointer;border:1px solid transparent;text-decoration:none!important;
  transition:transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease),background var(--dur) var(--ease);white-space:nowrap}
.btn--primary{background:var(--grad-aurora);color:var(--text-on-accent);box-shadow:var(--glow-accent)}
.btn--primary:hover{transform:translateY(-1px);box-shadow:var(--glow-accent-hover)}
.btn--primary:active{transform:none}
.btn--secondary{background:var(--surface-2);color:var(--text);border-color:var(--border-strong)}
.btn--secondary:hover{background:var(--surface-hover);border-color:var(--border-accent)}
.btn--ghost{background:transparent;color:var(--text-2)}
.btn--ghost:hover{background:var(--surface-1);color:var(--text)}
.btn--danger{background:var(--danger-bg);color:var(--danger);border-color:rgba(255,107,129,.4)}
.btn--danger:hover{background:rgba(255,107,129,.22)}
.btn--sm{min-height:34px;padding:0 var(--s-4);font-size:var(--fs-sm)}
.btn--lg{min-height:52px;padding:0 var(--s-6);font-size:var(--fs-md)}
.btn--block{width:100%}
.btn[disabled],.btn[aria-disabled="true"]{opacity:.5;cursor:not-allowed;transform:none!important;box-shadow:none!important}
.btn svg{width:18px;height:18px}

/* ─── Forms ──────────────────────────────────────────── */
.field{display:flex;flex-direction:column;gap:var(--s-1);margin-bottom:var(--s-4)}
.field>label,.label{font-size:var(--fs-sm);font-weight:600;color:var(--text-2)}
.field .hint{font-size:var(--fs-xs);color:var(--text-muted)}
.field .error{font-size:var(--fs-xs);color:var(--danger)}
/* The :not() chain is wrapped in :where() so this stays a DEFAULT, not a winner. Unwrapped it scored (0-4-1) — four
   attribute selectors — and silently beat every component rule that dresses an input: the header search lost its
   44px right padding and ran under the magnifier button, the hero field stood 45px beside its 52px button, the
   stepper and the builder's quantity boxes kept a border and stretched to the full column. :where() contributes
   nothing, so those rules apply again and .ptable td.add .qty no longer needs to replicate the chain to be heard. */
.input,input:where(:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=file])),select,textarea{
  width:100%;min-height:44px;padding:10px var(--s-3);font:inherit;font-size:max(15px,var(--fs-base));color:var(--text);
  background:var(--surface-sunken);border:1px solid var(--border-control);border-radius:var(--r-md);transition:border-color var(--dur),box-shadow var(--dur)}
/* v1.5.1 (visual QA 7): a control edge uses --border-control (≥3:1 on every page and card surface), not the decorative
   --border, which measured 1.16–1.22:1 around the builder's selects, quantity boxes and the quote form. */
input::placeholder,textarea::placeholder{color:var(--text-muted)}
input:not([type=checkbox]):not([type=radio]):focus,select:focus,textarea:focus,.input:focus{border-color:var(--border-accent);box-shadow:var(--ring-accent);outline:none}
input[aria-invalid="true"],select[aria-invalid="true"],textarea[aria-invalid="true"]{border-color:var(--danger)}
select{appearance:none;-webkit-appearance:none;padding-right:38px;background-image:var(--select-arrow);background-repeat:no-repeat;background-position:right 12px center}
select option{background:var(--surface-solid);color:var(--text)}
textarea{min-height:120px;resize:vertical;line-height:var(--lh)}
input[type=checkbox],input[type=radio]{width:18px;height:18px;accent-color:var(--accent);margin:0;vertical-align:-3px}
.check{display:flex;gap:var(--s-2);align-items:flex-start;font-size:var(--fs-sm);color:var(--text-2)}
.check input{margin-top:3px;flex:none}
.input-group{display:flex;gap:var(--s-2)}
.input-group>*{flex:1}
.stepper{display:inline-flex;align-items:stretch;border:1px solid var(--border);border-radius:var(--r-md);background:var(--surface-sunken);overflow:hidden}
.stepper button{width:40px;border:0;background:transparent;color:var(--text-2);font-size:var(--fs-lg);cursor:pointer}
.stepper button:hover{background:var(--surface-hover);color:var(--text)}
.stepper input{width:64px;min-height:42px;text-align:center;border:0;border-radius:0;background:transparent;font-variant-numeric:tabular-nums}
.segmented{display:inline-flex;padding:3px;border:1px solid var(--border);border-radius:var(--r-pill);background:var(--surface-sunken);gap:2px}
.segmented a,.segmented button,.segmented label{padding:6px 12px;border-radius:var(--r-pill);font-size:var(--fs-sm);font-weight:600;color:var(--text-2);cursor:pointer;border:0;background:transparent;font-family:inherit;text-decoration:none!important}
.segmented .is-active{background:var(--surface-3);color:var(--text);box-shadow:var(--shadow-1)}

/* ─── Badges ─────────────────────────────────────────── */
.badge{display:inline-flex;align-items:center;gap:6px;padding:3px 10px;border-radius:var(--r-pill);font-size:var(--fs-xs);font-weight:600;line-height:1.4;white-space:nowrap;background:var(--surface-3);color:var(--text-2);border:1px solid var(--border)}
.badge::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor;flex:none}
.badge--plain::before{display:none}
.badge--success,.badge--in{background:var(--success-bg);color:var(--success);border-color:rgba(59,232,176,.3)}
.badge--warning,.badge--low{background:var(--warning-bg);color:var(--warning);border-color:rgba(255,194,75,.3)}
.badge--danger{background:var(--danger-bg);color:var(--danger);border-color:rgba(255,107,129,.3)}
.badge--info{background:var(--info-bg);color:var(--info);border-color:rgba(95,216,255,.3)}
.badge--out{color:var(--stock-out)}
.badge--unknown{background:rgba(177,75,255,.14);color:var(--stock-unknown);border-color:rgba(177,75,255,.3)}
.badge--accent{background:var(--grad-aurora);color:var(--text-on-accent);border:0}
.badge--accent::before{background:var(--text-on-accent)}
.chip{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:var(--r-pill);background:var(--surface-2);border:1px solid var(--border);font-size:var(--fs-xs);color:var(--text-2)}
.chip a{color:var(--text-muted)}

/* ─── Tables ─────────────────────────────────────────── */
.table-wrap{overflow-x:auto;border:1px solid var(--border);border-radius:var(--r-lg);background:var(--surface-solid)}
table{width:100%;border-collapse:collapse;font-size:var(--fs-sm)}
thead th{position:sticky;top:0;background:var(--surface-3);color:var(--text-2);font-weight:600;text-align:left;padding:10px 12px;border-bottom:1px solid var(--border);white-space:nowrap;z-index:1}
tbody td{padding:10px 12px;border-bottom:1px solid var(--divider);vertical-align:middle}
tbody tr:nth-child(even){background:rgba(255,255,255,.02)}
tbody tr:hover{background:var(--surface-hover)}
tbody tr:last-child td{border-bottom:0}
td.price,th.price{font-weight:700;font-variant-numeric:tabular-nums;text-align:right;white-space:nowrap}
table a{color:var(--text)}
table a:hover{color:var(--text-link)}
tfoot td{padding:10px 12px;font-weight:600;border-top:1px solid var(--border)}
@media (max-width:699px){
  .table--stack thead{display:none}
  .table--stack tr{display:block;padding:var(--s-3) var(--s-4);border-bottom:1px solid var(--divider)}
  .table--stack td{display:flex;justify-content:space-between;gap:var(--s-3);padding:4px 0;border:0;text-align:right}
  .table--stack td::before{content:attr(data-label);color:var(--text-muted);font-weight:500;text-align:left}
  .table--stack td.price{text-align:right}
}

/* ─── Alerts / notices ───────────────────────────────── */
.notice{display:flex;gap:var(--s-3);padding:var(--s-3) var(--s-4);border-radius:var(--r-md);border:1px solid var(--border);background:var(--surface-2);font-size:var(--fs-sm);color:var(--text-2)}
.notice--info{border-color:rgba(95,216,255,.3);background:var(--info-bg)}
.notice--success{border-color:rgba(59,232,176,.3);background:var(--success-bg)}
.notice--warning{border-color:rgba(255,194,75,.3);background:var(--warning-bg)}
.notice--danger{border-color:rgba(255,107,129,.3);background:var(--danger-bg)}
.notice strong{color:var(--text)}
.flash{margin-bottom:var(--s-4)}

/* ─── Toast ──────────────────────────────────────────────
   Moved here from admin.css in the wave-2 pre-flight: the storefront loads tokens/base/site/catalog and NEVER
   admin.css, so site.js has been showing an add-to-cart confirmation that no stylesheet could make visible.
   Both shells load base.css, so one definition serves both.
   Markup is <div class="toast" role="status">: role="status" is an aria-live region, so the text is announced
   without moving focus. That means it must stay readable rather than decorative — hence the real surface, the
   border and a contrast-carrying colour, not a translucent overlay. */
.toast{position:fixed;bottom:20px;left:50%;transform:translate(-50%,20px);background:var(--surface-3);color:var(--text);padding:10px 18px;border-radius:var(--r-pill);border:1px solid var(--border);box-shadow:var(--shadow-3);opacity:0;transition:all var(--dur);z-index:100;max-width:min(92vw,520px);text-align:center;font-size:var(--fs-sm);font-weight:600;pointer-events:none}
.toast.is-visible{opacity:1;transform:translate(-50%,0);pointer-events:auto}
/* An empty live region must not sit on top of the page as an invisible click-blocker, and a screen reader should
   not read a toast that is not being shown. */
.toast:not(.is-visible){visibility:hidden}
/* Reduced motion: appear and disappear, never slide. */
@media (prefers-reduced-motion: reduce){
  .toast{transition:opacity var(--dur);transform:translate(-50%,0)}
  .toast.is-visible{transform:translate(-50%,0)}
}

/* ─── Misc ───────────────────────────────────────────── */
.gradient-text{background:var(--grad-aurora);-webkit-background-clip:text;background-clip:text;color:transparent}
.price{font-variant-numeric:tabular-nums;font-weight:700}
.price--lg{font-size:var(--fs-2xl);letter-spacing:-.02em}
.price--sub{font-size:var(--fs-sm);font-weight:500;color:var(--text-muted)}
.eyebrow{font-size:var(--fs-xs);font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--accent-text)}
.kbd{font-family:var(--font-mono);font-size:var(--fs-xs);padding:1px 6px;border:1px solid var(--border);border-bottom-width:2px;border-radius:4px;background:var(--surface-sunken)}
.dot{display:inline-block;width:8px;height:8px;border-radius:50%;background:currentColor;vertical-align:middle}
.skeleton{background:linear-gradient(90deg,var(--surface-1),var(--surface-3),var(--surface-1));background-size:200% 100%;animation:shimmer 1.4s infinite;border-radius:var(--r-sm);color:transparent}
@keyframes shimmer{to{background-position:-200% 0}}
details summary{cursor:pointer;list-style:none}
details summary::-webkit-details-marker{display:none}
/* --text-2, not --text-muted: the breadcrumb sits over the aurora glow at the top of the page, where muted text measured
   3.37:1 (visual QA 8, v1.5.1). */
.breadcrumb{display:flex;flex-wrap:wrap;gap:6px;font-size:var(--fs-sm);color:var(--text-2);margin-bottom:var(--s-4)}
.breadcrumb a{color:var(--text-2)}
.breadcrumb li{list-style:none}
.breadcrumb li+li::before{content:"/";margin-right:6px;color:var(--text-muted)}
.breadcrumb ol{display:contents;margin:0;padding:0}
.pagination{display:flex;gap:6px;flex-wrap:wrap;justify-content:center;margin-top:var(--s-5)}
.pagination a,.pagination span{min-width:38px;height:38px;display:inline-flex;align-items:center;justify-content:center;padding:0 10px;border-radius:var(--r-md);border:1px solid var(--border);background:var(--surface-1);color:var(--text-2);font-size:var(--fs-sm);text-decoration:none!important}
.pagination .is-active{background:var(--grad-aurora);color:var(--text-on-accent);border-color:transparent;font-weight:700}
.sparkline{width:100%;height:40px}

@media print{
  body{background:#fff;color:#000;font-size:11pt}
  .aurora,.site-header,.site-footer,.no-print,.btn{display:none!important}
  .card,.table-wrap{background:#fff;border-color:#ccc;box-shadow:none}
  table,thead th,tbody td{color:#000;background:#fff}
  a{color:#000}
}
