/*!
 * AimsCraft — Multi-purpose Ecommerce Frontend
 * File:      assets/css/base.css
 * Developer: Shahid Malla <https://shahidmalla.com>
 * Company:   ElySpace — owner of this source code
 * Copyright: © ElySpace. All rights reserved.
 */
/* ==========================================================================
   AimsCraft — base.css
   Modern reset + element defaults + a11y primitives + page shell.
   Loaded AFTER tokens.css and BEFORE utilities/components/layout/pages.
   Every colour here is a token. Fonts are linked from HTML (no @import).
   ========================================================================== */

/* ==========================================================================
   1. RESET
   ========================================================================== */
*,
*::before,
*::after {
  box-sizing: border-box;
}

:where(
  body, h1, h2, h3, h4, h5, h6, p, figure, figcaption, blockquote,
  dl, dd, ol, ul, fieldset, pre, hr
) {
  margin: 0;
}

:where(ul, ol)[class] {
  padding: 0;
  list-style: none;
}

:where(fieldset) {
  min-width: 0;
  padding: 0;
  border: 0;
}

:where(legend) {
  padding: 0;
}

:where(img, svg, video, canvas, audio, iframe, embed, object, picture) {
  display: block;
  max-width: 100%;
}

:where(img, video) {
  height: auto;
}

/* Zero layout shift: every <img>/<video> in the project ships width+height
   attributes (or an aspect-ratio from its component). Intrinsic sizing is
   honoured because height:auto above pairs with those attributes. */

:where(input, button, textarea, select, optgroup) {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
}

:where(button, [type="button"], [type="submit"], [type="reset"]) {
  -webkit-appearance: none;
  appearance: none;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
  text-align: inherit;
}

:where(textarea) {
  resize: vertical;
  min-height: 6rem;
}

:where(input, textarea, select) {
  accent-color: var(--brand);
}

::placeholder {
  color: var(--ink-3);
  opacity: 1;
}

:where(fieldset, dialog, details, summary, table) {
  color: inherit;
}

:where(dialog) {
  max-width: none;
  max-height: none;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
}

:where(dialog)::backdrop {
  background: var(--overlay);
}

:where(summary) {
  cursor: pointer;
  list-style: none;
}

:where(summary)::-webkit-details-marker {
  display: none;
}

:where(abbr[title]) {
  text-decoration: underline dotted;
  cursor: help;
}

:where(iframe) {
  border: 0;
}

[hidden] {
  display: none !important;
}

[inert],
[aria-disabled="true"],
.is-disabled {
  cursor: default;
}

[inert] {
  pointer-events: none;
  user-select: none;
}

/* ==========================================================================
   2. DOCUMENT
   ========================================================================== */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + var(--sp-4));
  tab-size: 4;
  -moz-tab-size: 4;
  scrollbar-color: var(--line-2) transparent;
  scrollbar-width: thin;
  scrollbar-gutter: stable;
}

body {
  min-height: 100dvh;
  margin: 0;
  overflow-x: clip;
  background-color: var(--bg);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--fs-md);
  font-weight: var(--fw-regular);
  line-height: var(--lh-normal);
  letter-spacing: var(--ls-normal);
  font-synthesis-weight: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior-y: none;
}

/* Lock scroll while a drawer / modal / sheet is open (set by app.js).
   Children (drawer bodies, sheets) keep their own scrolling. */
body.is-locked {
  overflow: hidden;
  overscroll-behavior: contain;
}

:target {
  scroll-margin-top: calc(var(--header-h) + var(--sp-6));
}

::selection {
  background-color: rgb(var(--brand-rgb) / .24);
  color: var(--ink);
}

/* ==========================================================================
   3. TYPOGRAPHY
   h1 / h2 use the display serif; h3–h6 stay in the sans for UI clarity.
   Override anywhere with .u-font-sans / .u-font-display.
   ========================================================================== */
:where(h1, h2, h3, h4, h5, h6) {
  color: var(--ink);
  font-weight: var(--fw-bold);
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-tight);
  text-wrap: balance;
}

h1, .h1 {
  font-family: var(--font-display);
  font-size: var(--fs-5xl);
  font-weight: var(--fw-regular);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tighter);
}

h2, .h2 {
  font-family: var(--font-display);
  font-size: var(--fs-4xl);
  font-weight: var(--fw-regular);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tighter);
}

h3, .h3 {
  font-size: var(--fs-2xl);
  font-weight: var(--fw-bold);
}

h4, .h4 {
  font-size: var(--fs-xl);
  font-weight: var(--fw-semibold);
}

h5, .h5 {
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
}

h6, .h6 {
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wide);
}

/* A size class on an h2 (h2.h5, the usual way to keep the outline while
   shrinking the look) kept the h2's condensed display serif and its -0.035em
   tracking, so panel and card headings came out as tiny cramped serif labels.
   The small steps are sans, like a bare h3–h6. */
.h3, .h4, .h5, .h6 { font-family: var(--font-sans); }
.h3, .h4, .h5 { letter-spacing: var(--ls-tight); }

.display {
  font-family: var(--font-display);
  font-size: var(--fs-6xl);
  font-weight: var(--fw-regular);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tighter);
}

p {
  text-wrap: pretty;
}

.lead {
  color: var(--ink-2);
  font-size: var(--fs-lg);
  line-height: var(--lh-relaxed);
}

small,
.small {
  font-size: var(--fs-sm);
}

strong, b {
  font-weight: var(--fw-semibold);
}

em, i {
  font-style: italic;
}

mark {
  padding: 0.1em 0.28em;
  border-radius: var(--r-xs);
  background-color: var(--brand-soft);
  color: var(--ink);
}

/* Prose flow: only unclassed content inside a text block gets rhythm */
:where(p, ul, ol, dl, blockquote, figure, pre, table):not([class]) + :where(p, ul, ol, dl, blockquote, figure, pre, table):not([class]) {
  margin-top: var(--sp-4);
}

:where(h2, h3, h4, h5, h6):not([class]) + :where(p, ul, ol):not([class]) {
  margin-top: var(--sp-3);
}

:where(ul, ol):not([class]) {
  padding-inline-start: var(--sp-5);
}

:where(ul, ol):not([class]) li + li {
  margin-top: var(--sp-2);
}

:where(ul, ol):not([class])::marker,
:where(ul, ol):not([class]) li::marker {
  color: var(--ink-3);
}

dt {
  font-weight: var(--fw-semibold);
}

dd {
  margin-inline-start: 0;
  color: var(--ink-2);
}

blockquote:not([class]) {
  padding-inline-start: var(--sp-5);
  border-inline-start: 3px solid var(--brand);
  color: var(--ink-2);
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  line-height: var(--lh-snug);
}

blockquote cite {
  display: block;
  margin-top: var(--sp-3);
  color: var(--ink-3);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-style: normal;
}

hr {
  height: 1px;
  margin-block: var(--sp-8);
  border: 0;
  background-color: var(--line);
}

/* An unstyled figure gets a muted caption. A caption that carries its own class
   does not: .auth-art__cite sits on a dark art panel and inherits the light ink
   from its parent, but this rule out-specified it and repainted the byline in
   --ink-3 — 1.4:1 on that panel, i.e. invisible on all four auth pages. */
figure:not([class]) figcaption:not([class]) {
  margin-top: var(--sp-2);
  color: var(--ink-3);
  font-size: var(--fs-sm);
}

address {
  font-style: normal;
}

/* --- Code -------------------------------------------------------------- */
code, kbd, samp, pre {
  font-family: var(--font-mono);
  font-size: 0.9em;
}

/* An inline <code> is a padded, bordered box on an inline baseline. Its box
   therefore sticks out ABOVE and BELOW its line box, and where two of them land
   on consecutive lines the chips collide — measured 54% overlap between order
   ids on track-order.html at 390px. Leading has to allow for the padding, so
   any block that contains one gets enough of it. */
:not(pre) > code {
  /* Two separate problems, two separate fixes.

     HORIZONTAL padding only: an inline box's padding does not push the line box
     apart, so vertical padding bleeds above and below its own line and two
     chips on consecutive lines overlapped by 54%.

     nowrap: a browser breaks at a HYPHEN by default, so "ELY-2026-10315" split
     across two lines and rendered as half a bordered chip on each — which is
     also why it kept reporting two client rects however overflow-wrap was set.
     An id is one token. */
  padding: 0 0.4em;
  border: 1px solid var(--line);
  border-radius: var(--r-xs);
  background-color: var(--surface-3);
  color: var(--ink);
  white-space: nowrap;
}

/* …except where the content is a URL or a path rather than an id. Those are
   long by nature and must wrap: with nowrap, `search.html?q=your+words` ran
   29px past a 390px viewport. */
/* :is(), not :where(): `:not(pre) > code` above scores (0,0,2) and :where()
   scores zero, so a :where() version of this rule lost the cascade and the URL
   kept overflowing. */
:is(dd, td, th, li) > code {
  white-space: normal;
  overflow-wrap: anywhere;
}

:where(p, li, dd, dt, td, th, figcaption, blockquote):has(> code) {
  line-height: var(--lh-loose, 1.9);
}

pre {
  overflow-x: auto;
  padding: var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background-color: var(--surface-2);
  line-height: var(--lh-normal);
  -webkit-overflow-scrolling: touch;
}

pre code {
  padding: 0;
  border: 0;
  background: none;
}

kbd {
  padding: 0.15em 0.45em;
  border: 1px solid var(--line-2);
  border-bottom-width: 2px;
  border-radius: var(--r-xs);
  background-color: var(--surface-2);
  font-size: var(--fs-xs);
}

/* --- Tables ------------------------------------------------------------ */
table {
  width: 100%;
  border-collapse: collapse;
  border-spacing: 0;
  font-variant-numeric: tabular-nums;
}

caption {
  margin-bottom: var(--sp-3);
  color: var(--ink-3);
  font-size: var(--fs-sm);
  text-align: start;
}

th,
td {
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--line);
  text-align: start;
  /* `middle` centres each cell independently, so as soon as ONE cell in a row
     wraps to two lines no two cells in that row share a first-line baseline and
     the row reads as a stagger. Top-align: every row then starts on one line. */
  vertical-align: top;
}

/* Numbers are not prose. Any cell marked numeric right-aligns and uses tabular
   figures so digits stack in columns and totals line up under each other. */
:where(th, td).u-num,
:where(th, td)[data-num],
:where(th, td):is(.ad-num, .od-num, .rt-num, .of-num, .oc-num) {
  text-align: end;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

thead th {
  color: var(--ink-2);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wider);
  text-transform: uppercase;
}

tbody tr:last-child > * {
  border-bottom: 0;
}

/* ==========================================================================
   4. LINKS
   Unclassed links read as prose links; classed links are components.
   ========================================================================== */
a {
  color: inherit;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}

a:where(:not([class])) {
  color: var(--brand-text);
  text-decoration: underline;
  text-decoration-color: rgb(var(--brand-rgb) / .35);
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
  transition: color var(--dur-2) var(--ease), text-decoration-color var(--dur-2) var(--ease);
}

@media (hover: hover) {
  a:where(:not([class])):hover {
    color: var(--brand-hover);
    text-decoration-color: currentColor;
  }
}

/* ==========================================================================
   5. FOCUS + SKIP LINK + SCREEN READERS
   ========================================================================== */
:focus {
  outline: none;
}

/* Outline follows the element's own border-radius, so components keep
   their shape while focused — never set a radius from this rule. */
:where(a, button, input, select, textarea, summary, dialog, [tabindex], [contenteditable="true"]):focus-visible {
  outline: var(--ring-w) solid var(--focus-ink);
  outline-offset: 2px;
}

.skip-link {
  position: fixed;
  top: var(--sp-2);
  left: var(--sp-2);
  z-index: var(--z-toast);
  padding: var(--sp-3) var(--sp-5);
  border-radius: var(--r-full);
  background-color: var(--brand);
  color: var(--brand-ink);
  box-shadow: var(--sh-3);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  text-decoration: none;
  /* -200% rather than just past the top edge: the shadow blurs further than
     the box, and at -100% its tail was visible above the promise line. */
  transform: translateY(-200%);
  transition: transform var(--dur-2) var(--ease);
}

.skip-link:focus-visible {
  outline-offset: 3px;
  transform: translateY(0);
}

.u-sr-only,
.sr-only {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0 0 0 0) !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* Visible again when focused — for "skip to content" style controls */
.u-sr-only-focusable:not(:focus):not(:focus-within) {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0 0 0 0) !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* ==========================================================================
   6. SCROLLBARS
   ========================================================================== */
::-webkit-scrollbar {
  width: 12px;
  height: 12px;
}

::-webkit-scrollbar-track {
  background: transparent;
}

::-webkit-scrollbar-thumb {
  border: 3px solid transparent;
  border-radius: var(--r-full);
  background-color: var(--line-2);
  background-clip: content-box;
}

::-webkit-scrollbar-thumb:hover {
  background-color: var(--ink-3);
  background-clip: content-box;
}

::-webkit-scrollbar-corner {
  background: transparent;
}

/* ==========================================================================
   7. ICONS — the one and only icon markup in this project:
   <svg class="icon" aria-hidden="true" focusable="false">
     <use href="assets/icons/sprite.svg#i-cart"></use>
   </svg>
   ========================================================================== */
/* THE ICON CONTRACT. This is the project's <Icon size="..."> — there is no
   component layer to put it in, so the contract lives here and `node build.mjs`
   fails the build if any icon markup deviates from it.

     <svg class="icon" aria-hidden="true" focusable="false">
       <use href="#i-cart"></use>
     </svg>

   Sizes are FIXED PIXELS, never em. When these were em-based an icon inherited
   the size of whatever text it sat beside, which produced thirty distinct icon
   sizes across the site and left 28 selectors under the 16px floor — .icon--xs
   rendered at 9.7px. An icon scale that changes with its context is not a scale.

     .icon            20px   default (md)
     .icon--sm        16px   the floor for anything interactive or standalone
     .icon--lg        24px
     .icon--xl        32px
     .icon--badge     14px   the ONLY size below the floor; badges/tags only

   `.icon--xs` is deliberately gone. Every former use was either a badge glyph
   (now --badge) or an under-sized inline icon (now --sm). */
.icon {
  display: inline-block;
  flex: none;
  inline-size: var(--icon-md);
  block-size: var(--icon-md);
  vertical-align: middle;
  color: inherit;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
}

.icon--badge { inline-size: var(--icon-badge); block-size: var(--icon-badge); }
.icon--sm    { inline-size: var(--icon-sm);    block-size: var(--icon-sm); }
.icon--md    { inline-size: var(--icon-md);    block-size: var(--icon-md); }
.icon--lg    { inline-size: var(--icon-lg);    block-size: var(--icon-lg); }
.icon--xl    { inline-size: var(--icon-xl);    block-size: var(--icon-xl); }

/* ==========================================================================
   8. PAGE SHELL
   ========================================================================== */
.container,
.container--wide,
.container--narrow {
  width: 100%;
  margin-inline: auto;
  padding-inline: max(var(--container-pad), var(--safe-l)) max(var(--container-pad), var(--safe-r));
}

.container { max-width: calc(var(--container) + var(--container-pad) * 2); }
.container--wide { max-width: calc(var(--container-wide) + var(--container-pad) * 2); }
.container--narrow { max-width: calc(var(--container-narrow) + var(--container-pad) * 2); }

.section {
  --section-y: clamp(2.5rem, 6vw, 6rem);
  padding-block: var(--section-y);
}

.section--tight { --section-y: clamp(1.5rem, 4vw, 3rem); }
.section--flush { --section-y: 0px; }

/* Far-down sections opt into cheaper rendering */
.section--defer {
  content-visibility: auto;
  contain-intrinsic-size: auto 600px;
}

/* ==========================================================================
   9. REDUCED MOTION
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }

  /* Motion-driven decoration is neutralised, not just sped up */
  [data-animate],
  .u-parallax {
    transform: none !important;
    opacity: 1 !important;
  }
}

/* ==========================================================================
   10. PRINT
   The only place in the project where raw colour keywords are allowed.
   ========================================================================== */
@media print {
  *,
  *::before,
  *::after {
    background: transparent !important;
    color: black !important;
    box-shadow: none !important;
    text-shadow: none !important;
  }

  html,
  body {
    background: white !important;
  }

  .site-header,
  .site-footer,
  .tabbar,
  .drawer,
  .sheet,
  .modal,
  .toast,
  .skip-link,
  [data-drawer],
  [data-no-print] {
    display: none !important;
  }

  main {
    padding: 0 !important;
  }

  a:where(:not([class]))[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: var(--fs-xs);
    word-break: break-all;
  }

  .container,
  .container--wide,
  .container--narrow {
    max-width: none;
    padding-inline: 0;
  }

  h1, h2, h3, h4, h5, h6 {
    break-after: avoid;
  }

  img,
  table,
  figure,
  pre {
    break-inside: avoid;
  }
}
