/* ==========================================================================
   El Noa Noa Supermarket — COMPONENTS
   Buttons, forms, cards, badges, alerts, modal, toast, navigation primitives,
   media slots and the brand pattern.

   Every value comes from a token. Nothing here hard-codes a colour, size or
   duration, so a token change restyles the whole system.
   ========================================================================== */

/* ==========================================================================
   1. ICONS
   Rendered from a single SVG sprite:
     <svg class="icon" aria-hidden="true"><use href="/assets/images/icons.svg#cart"></use></svg>
   Icons inherit the current text colour and scale with the font size.
   ========================================================================== */

.icon {
  width: 1.25em;
  height: 1.25em;
  flex: 0 0 auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: middle;
}

.icon-sm { width: 1em;    height: 1em; }
.icon-lg { width: 1.5em;  height: 1.5em; }
.icon-xl { width: 2rem;   height: 2rem; }
.icon-2xl{ width: 2.75rem; height: 2.75rem; }

/* Icon inside a tinted rounded tile, as used by trust indicators. */
.icon-tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: var(--radius-md);
  background: var(--color-primary-subtle);
  color: var(--color-primary);
  flex: 0 0 auto;
}

.icon-tile-accent {
  background: var(--color-accent-subtle);
  color: var(--yellow-700);
}

.icon-tile-lg {
  width: 64px;
  height: 64px;
  border-radius: var(--radius-lg);
}

/* ==========================================================================
   2. BUTTONS
   .btn-primary  blue on white text   — the workhorse (Add to Cart)
   .btn-accent   yellow on blue text  — high-impact CTA (Shop Now)
   .btn-outline  bordered neutral     — secondary action
   .btn-ghost    text only            — tertiary action
   .btn-danger   destructive
   .btn-inverse  for dark backgrounds
   ========================================================================== */

.btn {
  --btn-bg: transparent;
  --btn-fg: var(--color-text);
  --btn-border: transparent;
  --btn-bg-hover: transparent;
  --btn-shadow: none;

  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--btn-height);
  padding-inline: var(--space-5);
  padding-block: var(--space-2);
  border: var(--border-width) solid var(--btn-border);
  border-radius: var(--btn-radius);
  background-color: var(--btn-bg);
  color: var(--btn-fg);
  box-shadow: var(--btn-shadow);
  font-family: var(--btn-font);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  transition: background-color var(--duration-fast) var(--ease),
              border-color var(--duration-fast) var(--ease),
              color var(--duration-fast) var(--ease),
              box-shadow var(--duration-fast) var(--ease),
              transform var(--duration-fast) var(--ease);
}

.btn:hover {
  background-color: var(--btn-bg-hover);
  color: var(--btn-fg);
  text-decoration: none;
}

.btn:active {
  transform: translateY(1px);
}

.btn:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}

.btn:disabled,
.btn.is-disabled,
.btn[aria-disabled="true"] {
  opacity: 0.5;
  pointer-events: none;
  transform: none;
}

.btn-primary {
  --btn-bg: var(--color-primary);
  --btn-fg: var(--color-on-primary);
  --btn-bg-hover: var(--color-primary-hover);
  --btn-shadow: var(--shadow-xs);
}

.btn-primary:active { background-color: var(--color-primary-active); }

/* The yellow CTA is identified by its label, which sits at 9.28:1 against the
   fill. The darker yellow border is not required for conformance; it keeps the
   edge crisp when the button sits on a near-white surface. */
.btn-accent {
  --btn-bg: var(--color-accent);
  --btn-fg: var(--color-on-accent);
  --btn-border: var(--yellow-500);
  --btn-bg-hover: var(--color-accent-hover);
  --btn-shadow: var(--shadow-xs);
}

.btn-accent:hover { border-color: var(--yellow-600); }

.btn-accent:active { background-color: var(--color-accent-active); }

.btn-outline {
  --btn-bg: var(--color-surface);
  --btn-fg: var(--color-primary);
  --btn-border: var(--color-border-strong);
  --btn-bg-hover: var(--color-primary-subtle);
}

.btn-outline:hover { border-color: var(--color-primary); }

.btn-ghost {
  --btn-fg: var(--color-primary);
  --btn-bg-hover: var(--color-primary-subtle);
  padding-inline: var(--space-3);
}

.btn-danger {
  --btn-bg: var(--color-danger);
  --btn-fg: var(--gray-0);
  --btn-bg-hover: var(--red-700);
}

.btn-danger:focus-visible { box-shadow: var(--shadow-focus-danger); }

/* On a blue or photographic background. */
.btn-inverse {
  --btn-bg: transparent;
  --btn-fg: var(--gray-0);
  --btn-border: rgba(255, 255, 255, 0.6);
  --btn-bg-hover: rgba(255, 255, 255, 0.14);
}

.btn-inverse:focus-visible {
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.45);
}

/* Sizes */
.btn-sm {
  min-height: var(--btn-height-sm);
  padding-inline: var(--space-3);
  font-size: var(--text-sm);
  gap: var(--space-1);
}

.btn-lg {
  min-height: var(--btn-height-lg);
  padding-inline: var(--space-8);
  font-size: var(--text-lg);
}

.btn-block { display: flex; width: 100%; }

.btn-pill { border-radius: var(--radius-full); }

/* Square icon-only button. Always needs an accessible name. */
.btn-icon {
  padding: 0;
  width: var(--btn-height);
  min-height: var(--btn-height);
  border-radius: var(--radius-full);
}

.btn-icon.btn-sm { width: var(--btn-height-sm); }
.btn-icon.btn-lg { width: var(--btn-height-lg); }

/* Loading state: the label is replaced by a spinner, width is preserved so
   the layout does not jump. */
.btn.is-loading {
  color: transparent !important;
  pointer-events: none;
  position: relative;
}

.btn.is-loading::after {
  content: "";
  position: absolute;
  width: 1.15em;
  height: 1.15em;
  border: 2px solid currentColor;
  border-radius: 50%;
  border-top-color: transparent;
  color: var(--btn-fg);
  animation: noa-spin 0.7s linear infinite;
}

@keyframes noa-spin {
  to { transform: rotate(360deg); }
}

/* Touch devices get the full comfortable target regardless of size class. */
@media (pointer: coarse) {
  .btn-sm { min-height: var(--tap-target); }
}

/* ==========================================================================
   3. FORM CONTROLS
   ========================================================================== */

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.label {
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--color-text);
}

.label .required {
  color: var(--color-danger);
  margin-inline-start: 2px;
}

.input,
.select,
.textarea {
  width: 100%;
  min-height: var(--input-height);
  padding: var(--space-2) var(--space-3);
  background-color: var(--input-bg);
  border: var(--border-width) solid var(--color-border-strong);
  border-radius: var(--input-radius);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.4;
  transition: var(--transition-colors), box-shadow var(--duration-fast) var(--ease);
  appearance: none;
}

.textarea {
  min-height: 120px;
  padding: var(--space-3);
  line-height: var(--leading-normal);
}

.input::placeholder,
.textarea::placeholder {
  color: var(--color-text-subtle);
}

.input:hover,
.select:hover,
.textarea:hover {
  border-color: var(--color-primary-border);
}

.input:focus,
.select:focus,
.textarea:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: var(--shadow-focus);
}

.input:disabled,
.select:disabled,
.textarea:disabled {
  background-color: var(--color-surface-sunken);
  color: var(--color-text-subtle);
  cursor: not-allowed;
}

.input[readonly] {
  background-color: var(--color-surface-sunken);
}

/* Native select needs its own chevron once appearance is removed. */
.select {
  padding-inline-end: var(--space-10);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234B5563' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-3) center;
  background-size: 1.15em;
  cursor: pointer;
}

/* Invalid state. Driven by a class, not :invalid, so the error only shows
   after the server or an explicit client check has run. */
.field.has-error .input,
.field.has-error .select,
.field.has-error .textarea,
.input.is-invalid {
  border-color: var(--color-danger);
}

.field.has-error .input:focus,
.input.is-invalid:focus {
  box-shadow: var(--shadow-focus-danger);
}

.field-help {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.field-error {
  display: flex;
  align-items: flex-start;
  gap: var(--space-1);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--color-danger);
}

/* Input with a leading or trailing adornment (search field, price field). */
.input-group {
  display: flex;
  align-items: stretch;
  width: 100%;
}

.input-group .input {
  border-start-end-radius: 0;
  border-end-end-radius: 0;
  border-inline-end: 0;
}

.input-group .btn {
  border-start-start-radius: 0;
  border-end-start-radius: 0;
  flex: 0 0 auto;
}

.input-affix {
  display: inline-flex;
  align-items: center;
  padding-inline: var(--space-3);
  background: var(--color-surface-sunken);
  border: var(--border-width) solid var(--color-border-strong);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

.input-affix:first-child {
  border-inline-end: 0;
  border-start-start-radius: var(--input-radius);
  border-end-start-radius: var(--input-radius);
}

.input-group .input:not(:first-child) {
  border-start-start-radius: 0;
  border-end-start-radius: 0;
}

/* Checkbox and radio. The native control is kept for accessibility and
   restyled with accent-color rather than being replaced. */
.check {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  cursor: pointer;
  font-size: var(--text-base);
  line-height: 1.4;
  min-height: var(--tap-target);
  align-content: center;
  flex-wrap: wrap;
}

.check input[type="checkbox"],
.check input[type="radio"] {
  width: 20px;
  height: 20px;
  margin: 2px 0 0;
  accent-color: var(--color-primary);
  cursor: pointer;
  flex: 0 0 auto;
}

.check input:disabled {
  cursor: not-allowed;
}

.check input:disabled + span {
  color: var(--color-text-subtle);
}

/* Switch. align-self, as for .qty, keeps the hit area matched to the visible
   control rather than stretching across the whole field. */
.switch {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: var(--space-3);
  cursor: pointer;
}

.switch input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

/* The off state uses --gray-400 so the white knob keeps 3:1 against the track
   and the state stays distinguishable without relying on colour alone. */
.switch-track {
  position: relative;
  width: 44px;
  height: 26px;
  border-radius: var(--radius-full);
  background: var(--gray-400);
  transition: background-color var(--duration) var(--ease);
  flex: 0 0 auto;
}

.switch-track::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--gray-0);
  box-shadow: var(--shadow-sm);
  transition: transform var(--duration) var(--ease);
}

.switch input:checked + .switch-track {
  background: var(--color-primary);
}

.switch input:checked + .switch-track::after {
  transform: translateX(18px);
}

.switch input:focus-visible + .switch-track {
  box-shadow: var(--shadow-focus);
}

/* Quantity stepper used by cart and product cards.
   align-self keeps it at its intrinsic width: as a flex item inside .field its
   inline-flex is blockified, so without this it would stretch the full column
   and present a click target far wider than the control looks. */
.qty {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  border: var(--border-width) solid var(--color-border-strong);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--color-surface);
}

.qty button {
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-primary);
  transition: var(--transition-colors);
}

.qty button:hover:not(:disabled) {
  background: var(--color-primary-subtle);
}

.qty button:disabled {
  color: var(--color-text-subtle);
}

.qty input {
  width: 48px;
  height: 40px;
  border: 0;
  border-inline: var(--border-width) solid var(--color-border);
  text-align: center;
  font-weight: var(--weight-semibold);
  font-family: var(--font-heading);
  background: transparent;
  -moz-appearance: textfield;
}

.qty input::-webkit-outer-spin-button,
.qty input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.qty input:focus {
  outline: none;
  background: var(--color-primary-subtle);
}

/* ==========================================================================
   4. MEDIA SLOTS AND PLACEHOLDERS
   Every image sits in a ratio-locked slot and is cropped with object-fit.
   Real photography replaces the placeholder without any markup change.

   Responsive variants generated in Phase 13 (ImageProcessor):
     thumb  160w | small 320w | medium 640w | large 1024w | xl 1600w
   Recommended sizes attribute per slot:
     product card  "(min-width:1024px) 260px, (min-width:768px) 33vw, 50vw"
     category tile "(min-width:768px) 160px, 33vw"
     hero          "100vw"
   ========================================================================== */

.media {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--radius-md);
  background-color: var(--color-surface-sunken);
  aspect-ratio: var(--media-ratio, var(--ratio-square));
}

.media img,
.media video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--media-position);
}

/* Contain instead of crop: packaged goods that must not be cut off. */
.media-contain img {
  object-fit: contain;
  padding: var(--space-3);
}

.media-square   { --media-ratio: var(--ratio-square); }
.media-product  { --media-ratio: var(--ratio-product); }
.media-card     { --media-ratio: var(--ratio-card); }
.media-wide     { --media-ratio: var(--ratio-wide); }
.media-banner   { --media-ratio: var(--ratio-banner); }
.media-hero     { --media-ratio: var(--ratio-hero); }
.media-portrait { --media-ratio: var(--ratio-portrait); }

/* Development placeholder. Brand-tinted and marked with the meander motif so a
   missing asset is unmistakable, but the pattern sits on its own layer at low
   opacity: it must read as a quiet texture behind the glyph, never as a busy
   wallpaper competing with the surrounding card content. */
.media-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--media-placeholder-bg);
  color: var(--media-placeholder-fg);
  isolation: isolate;
}

.media-placeholder::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image: var(--pattern-meander);
  background-size: var(--pattern-size);
  background-repeat: repeat;
  opacity: var(--media-placeholder-pattern-opacity);
  pointer-events: none;
}

.media-placeholder .icon {
  position: relative;
  z-index: 1;
  width: 2.5rem;
  height: 2.5rem;
  stroke-width: 1.5;
  color: var(--blue-400);
}

.media-placeholder-label {
  position: absolute;
  z-index: 1;
  inset-block-end: var(--space-2);
  inset-inline: var(--space-2);
  text-align: center;
  font-family: var(--font-heading);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--blue-400);
}

/* Zoom on hover, for product cards on pointer devices only. */
@media (hover: hover) {
  .media-zoom img {
    transition: transform var(--duration-slow) var(--ease);
  }

  .card:hover .media-zoom img,
  .media-zoom:hover img {
    transform: scale(1.06);
  }
}

/* ==========================================================================
   5. CARDS
   ========================================================================== */

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--card-bg);
  border: var(--border-width) solid var(--card-border);
  border-radius: var(--card-radius);
  overflow: hidden;
  transition: border-color var(--duration) var(--ease),
              box-shadow var(--duration) var(--ease),
              transform var(--duration) var(--ease);
}

/* Interactive cards lift slightly. Depth is a tinted brand shadow, not a
   heavy neutral drop shadow. */
.card-interactive:hover {
  border-color: var(--color-primary-border);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

.card-interactive:focus-within {
  border-color: var(--color-primary);
  box-shadow: var(--shadow-focus);
}

.card-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
  flex: 1 1 auto;
}

.card-header {
  padding: var(--space-4);
  border-bottom: var(--border-width) solid var(--color-border);
}

.card-footer {
  padding: var(--space-4);
  border-top: var(--border-width) solid var(--color-border);
  margin-top: auto;
}

.card-title {
  font-family: var(--font-heading);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
  color: var(--color-text-strong);
  margin: 0;
}

.card-flat   { border-radius: var(--radius-md); box-shadow: none; }
.card-raised { border-color: transparent; box-shadow: var(--shadow-sm); }
.card-accent { border-top: 3px solid var(--color-accent); }

/* Stretched link: makes the whole card clickable from one anchor while the
   accessible name stays on that anchor only. */
.stretched-link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

/* Controls that must stay clickable above a stretched link.
   .wishlist-btn is deliberately excluded: it sets its own position:absolute and
   z-index, and listing it here would override that and drop it out of the
   corner of the image slot. */
.card .btn,
.card .qty {
  position: relative;
  z-index: 2;
}

/* Price block. */
.price {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-2);
  font-family: var(--font-heading);
}

.price-current {
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  color: var(--color-price);
}

.price-sale .price-current {
  color: var(--color-price-sale);
}

.price-compare {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--color-price-compare);
  text-decoration: line-through;
}

.price-unit {
  font-size: var(--text-xs);
  font-weight: var(--weight-regular);
  color: var(--color-text-muted);
}

/* Wishlist heart pinned to the top corner of a media slot. */
.wishlist-btn {
  position: absolute;
  top: var(--space-2);
  inset-inline-end: var(--space-2);
  z-index: 2;
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  color: var(--color-text-muted);
  box-shadow: var(--shadow-xs);
  transition: var(--transition-colors), transform var(--duration-fast) var(--ease);
}

.wishlist-btn:hover {
  color: var(--color-danger);
  transform: scale(1.08);
}

.wishlist-btn[aria-pressed="true"] {
  color: var(--color-danger);
}

.wishlist-btn[aria-pressed="true"] .icon {
  fill: currentColor;
}

/* Star rating. */
.rating {
  display: inline-flex;
  align-items: center;
  gap: 1px;
  color: var(--yellow-400);
}

.rating .icon {
  width: 0.95rem;
  height: 0.95rem;
  fill: currentColor;
  stroke: none;
}

.rating .icon.is-empty {
  fill: var(--gray-300);
}

.rating-count {
  margin-inline-start: var(--space-1);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

/* On phones a product card is about 130px wide and several Spanish names need
   three or four lines. Clamping to two cut the pack size off the end
   ("Chorizo Colombiano (1…"), which is the part a shopper is looking for.
   Grid rows already equalise card heights, so the clamp is not what keeps a
   rail or a catalog page tidy at this width.

   This lives with the card rather than with one page's stylesheet: the shop,
   the departments, search and the homepage all render the same component, and
   the rule was silently missing from every page but the homepage. */
@media (max-width: 767.98px) {
  .product-card .card-title.clamp-2 {
    display: block;
    overflow: visible;
    -webkit-line-clamp: none;
    line-clamp: none;
  }
}

/* Add to cart from the card: a quantity and one button, above the stretched
   link so both stay clickable. On phones the quantity drops out and the button
   adds one; the product page still has the full quantity control. */
.product-card__add {
  position: relative;
  z-index: 2;
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.product-card__qty {
  width: 4rem;
  min-height: 40px;
  padding-inline: var(--space-2);
  text-align: center;
}

.product-card__add-btn {
  flex: 1;
  min-height: 40px;
  justify-content: center;
}

@media (max-width: 479.98px) {
  .product-card__qty { display: none; }
}

/* ==========================================================================
   6. BADGES, CHIPS AND TAGS
   Product badges follow the approved design: SALE red, BEST SELLER green,
   NEW and LOCAL blue, LATIN FAVORITE and WEEKLY DEAL yellow.
   ========================================================================== */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 3px var(--space-2);
  border-radius: var(--radius-xs);
  background: var(--color-surface-sunken);
  color: var(--color-text);
  font-family: var(--font-heading);
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  line-height: 1.4;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  white-space: nowrap;
}

.badge-sale       { background: var(--color-danger);  color: var(--gray-0); }
.badge-new        { background: var(--color-primary); color: var(--gray-0); }
.badge-bestseller { background: var(--color-success); color: var(--gray-0); }
.badge-local      { background: var(--blue-500);      color: var(--gray-0); }
.badge-latin      { background: var(--color-accent);  color: var(--color-on-accent); }
.badge-organic    { background: var(--green-100);     color: var(--green-700); }
.badge-deal       { background: var(--color-accent);  color: var(--color-on-accent); }
.badge-limited    { background: var(--amber-100);     color: var(--amber-700); }
.badge-trending   { background: var(--color-primary); color: var(--gray-0); }
.badge-imported   { background: var(--gray-0);        color: var(--color-text); box-shadow: inset 0 0 0 1px var(--color-border); text-transform: none; }
.badge-stock      { background: var(--amber-100);     color: var(--amber-700); }
.badge-back       { background: var(--green-100);     color: var(--green-700); }
.badge-neutral    { background: var(--color-surface-sunken); color: var(--color-text-muted); }

.badge-outline {
  background: transparent;
  border: var(--border-width) solid var(--color-border-strong);
  color: var(--color-text-muted);
}

.badge-lg {
  font-size: var(--text-xs);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-sm);
}

/* Stack of badges over a product image. */
.badge-stack {
  position: absolute;
  top: var(--space-2);
  inset-inline-start: var(--space-2);
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-1);
}

/* Status pill for orders and stock. */
.status {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  background: var(--color-surface-sunken);
  color: var(--color-text-muted);
}

.status::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

.status-success { background: var(--color-success-bg); color: var(--green-700); }
.status-warning { background: var(--color-warning-bg); color: var(--amber-700); }
.status-danger  { background: var(--color-danger-bg);  color: var(--red-700); }
.status-info    { background: var(--color-info-bg);    color: var(--blue-700); }

/* Filter chip. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 36px;
  padding: var(--space-1) var(--space-4);
  border: var(--border-width) solid var(--color-border-strong);
  border-radius: var(--radius-full);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: var(--transition-colors);
}

.chip:hover {
  border-color: var(--color-primary);
  background: var(--color-primary-subtle);
  color: var(--color-primary);
}

.chip[aria-pressed="true"],
.chip.is-active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-on-primary);
}

/* ==========================================================================
   7. ALERTS
   ========================================================================== */

.alert {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4);
  border: var(--border-width) solid var(--color-border);
  border-inline-start: 3px solid var(--color-text-muted);
  border-radius: var(--radius);
  background: var(--color-surface);
  color: var(--color-text);
}

.alert .icon {
  flex: 0 0 auto;
  margin-top: 2px;
}

.alert-title {
  font-family: var(--font-heading);
  font-weight: var(--weight-semibold);
  margin-bottom: var(--space-1);
}

.alert-body { flex: 1 1 auto; }

.alert-body > p:last-child { margin-bottom: 0; }

.alert-close {
  flex: 0 0 auto;
  color: currentColor;
  opacity: 0.6;
  padding: var(--space-1);
  border-radius: var(--radius-xs);
}

.alert-close:hover { opacity: 1; }

.alert-info {
  background: var(--color-info-bg);
  border-color: var(--color-info-border);
  border-inline-start-color: var(--color-info);
  color: var(--blue-800);
}

.alert-success {
  background: var(--color-success-bg);
  border-color: var(--color-success-border);
  border-inline-start-color: var(--color-success);
  color: var(--green-700);
}

.alert-warning {
  background: var(--color-warning-bg);
  border-color: var(--color-warning-border);
  border-inline-start-color: var(--color-warning);
  color: var(--amber-700);
}

.alert-danger {
  background: var(--color-danger-bg);
  border-color: var(--color-danger-border);
  border-inline-start-color: var(--color-danger);
  color: var(--red-700);
}

/* ==========================================================================
   8. MODAL
   Behaviour lives in assets/js/modules/modal.js. This file only styles it.
   ========================================================================== */

.modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 0;
}

@media (min-width: 768px) {
  .modal {
    align-items: center;
    padding: var(--space-6);
  }
}

.modal[hidden] { display: none; }

.modal-backdrop {
  position: absolute;
  inset: 0;
  background: var(--color-overlay);
  backdrop-filter: blur(2px);
  animation: noa-fade-in var(--duration) var(--ease);
}

.modal-dialog {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: var(--modal-width, 520px);
  max-height: min(90vh, 800px);
  background: var(--color-surface);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  box-shadow: var(--shadow-xl);
  /* Mobile default is a bottom sheet. */
  animation: noa-sheet-in var(--duration-slow) var(--ease-out);
}

@media (min-width: 768px) {
  .modal-dialog {
    border-radius: var(--radius-lg);
    animation: noa-modal-in var(--duration) var(--ease-out);
  }
}

.modal-sm { --modal-width: 400px; }
.modal-lg { --modal-width: 720px; }
.modal-xl { --modal-width: 960px; }

.modal-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5);
  border-bottom: var(--border-width) solid var(--color-border);
}

.modal-title {
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  margin: 0;
}

.modal-close {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-full);
  color: var(--color-text-muted);
  transition: var(--transition-colors);
}

.modal-close:hover {
  background: var(--color-surface-sunken);
  color: var(--color-text);
}

.modal-body {
  padding: var(--space-5);
  overflow-y: auto;
  flex: 1 1 auto;
}

.modal-footer {
  display: flex;
  gap: var(--space-3);
  justify-content: flex-end;
  padding: var(--space-5);
  border-top: var(--border-width) solid var(--color-border);
}

@media (max-width: 479.98px) {
  .modal-footer {
    flex-direction: column-reverse;
  }

  .modal-footer .btn { width: 100%; }
}

@keyframes noa-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes noa-modal-in {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to   { opacity: 1; transform: none; }
}

@keyframes noa-sheet-in {
  from { transform: translateY(100%); }
  to   { transform: none; }
}

/* ==========================================================================
   9. TOAST
   Behaviour lives in assets/js/modules/toast.js.
   ========================================================================== */

.toast-region {
  position: fixed;
  z-index: var(--z-toast);
  inset-block-start: auto;
  inset-block-end: var(--space-4);
  inset-inline: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  pointer-events: none;
}

@media (min-width: 768px) {
  .toast-region {
    inset-block-start: var(--space-6);
    inset-block-end: auto;
    inset-inline-start: auto;
    inset-inline-end: var(--space-6);
    width: min(380px, calc(100vw - var(--space-12)));
  }
}

.toast {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-inline-start: 3px solid var(--color-primary);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  pointer-events: auto;
  animation: noa-toast-in var(--duration) var(--ease-out);
}

.toast.is-leaving {
  animation: noa-toast-out var(--duration) var(--ease) forwards;
}

.toast-icon { flex: 0 0 auto; margin-top: 2px; color: var(--color-primary); }
.toast-body { flex: 1 1 auto; font-size: var(--text-sm); }

.toast-title {
  font-family: var(--font-heading);
  font-weight: var(--weight-semibold);
  font-size: var(--text-sm);
}

.toast-close {
  flex: 0 0 auto;
  color: var(--color-text-subtle);
  padding: var(--space-1);
  border-radius: var(--radius-xs);
}

.toast-close:hover { color: var(--color-text); }

.toast-success { border-inline-start-color: var(--color-success); }
.toast-success .toast-icon { color: var(--color-success); }
.toast-danger  { border-inline-start-color: var(--color-danger); }
.toast-danger .toast-icon  { color: var(--color-danger); }
.toast-warning { border-inline-start-color: var(--color-warning); }
.toast-warning .toast-icon { color: var(--color-warning); }

@keyframes noa-toast-in {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

@keyframes noa-toast-out {
  to { opacity: 0; transform: translateY(-8px); }
}

/* ==========================================================================
   10. NAVIGATION PRIMITIVES
   The primitives the design system needs. The actual site header, mega menu
   and footer are built in Phase 3 from these pieces.
   ========================================================================== */

.nav {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

.nav-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius);
  color: var(--color-text);
  font-family: var(--font-heading);
  font-weight: var(--weight-medium);
  text-decoration: none;
  transition: var(--transition-colors);
}

.nav-link:hover {
  background: var(--color-primary-subtle);
  color: var(--color-primary);
}

.nav-link[aria-current],
.nav-link.is-active {
  color: var(--color-primary);
  font-weight: var(--weight-semibold);
}

/* Navigation on the blue bar. */
.nav-inverse .nav-link {
  color: rgba(255, 255, 255, 0.88);
}

.nav-inverse .nav-link:hover {
  background: rgba(255, 255, 255, 0.12);
  color: var(--gray-0);
}

.nav-inverse .nav-link[aria-current],
.nav-inverse .nav-link.is-active {
  color: var(--color-accent);
}

/* Tabs. */
.tabs {
  display: flex;
  gap: var(--space-1);
  border-bottom: var(--border-width) solid var(--color-border);
  overflow-x: auto;
  scrollbar-width: none;
}

.tabs::-webkit-scrollbar { display: none; }

.tab {
  padding: var(--space-3) var(--space-4);
  border-bottom: var(--border-width-thick) solid transparent;
  margin-bottom: -1px;
  color: var(--color-text-muted);
  font-family: var(--font-heading);
  font-weight: var(--weight-medium);
  white-space: nowrap;
  text-decoration: none;
  transition: var(--transition-colors);
}

.tab:hover { color: var(--color-primary); }

.tab[aria-selected="true"],
.tab.is-active {
  color: var(--color-primary);
  border-bottom-color: var(--color-primary);
  font-weight: var(--weight-semibold);
}

/* Breadcrumb. */
.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.breadcrumb ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  list-style: none;
  margin: 0;
  padding: 0;
}

.breadcrumb li {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.breadcrumb li:not(:last-child)::after {
  content: "";
  width: 5px;
  height: 5px;
  border-top: 1.5px solid var(--color-text-subtle);
  border-right: 1.5px solid var(--color-text-subtle);
  transform: rotate(45deg);
}

.breadcrumb a { color: var(--color-text-muted); text-decoration: none; }
.breadcrumb a:hover { color: var(--color-primary); }
.breadcrumb [aria-current] { color: var(--color-text); font-weight: var(--weight-medium); }

/* Pagination. */
.pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  margin-top: var(--space-10, 2.5rem);
}

.page-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 40px;
  height: 40px;
  padding-inline: var(--space-2);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface);
  color: var(--color-text);
  font-family: var(--font-heading);
  font-weight: var(--weight-medium);
  text-decoration: none;
  transition: var(--transition-colors);
}

.page-link:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

.page-link[aria-current="page"] {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-on-primary);
}

.page-link.is-disabled {
  color: var(--color-text-subtle);
  pointer-events: none;
}

/* Section heading with an optional trailing action. */
.section-heading {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-6);
}

.section-heading h2 { margin: 0; }

/* ==========================================================================
   11. STATE COMPONENTS
   ========================================================================== */

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-3);
  padding: var(--space-12) var(--space-6);
  color: var(--color-text-muted);
}

.empty-state .icon-tile { margin-bottom: var(--space-2); }

.empty-state-title {
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  color: var(--color-text-strong);
}

/* Skeleton loading block. */
.skeleton {
  background: linear-gradient(
    90deg,
    var(--gray-100) 25%,
    var(--gray-200) 37%,
    var(--gray-100) 63%
  );
  background-size: 400% 100%;
  border-radius: var(--radius-sm);
  animation: noa-shimmer 1.4s ease-in-out infinite;
}

.skeleton-text {
  height: 0.85em;
  margin-block: 0.32em;
}

.skeleton-title { height: 1.2em; width: 60%; }

@keyframes noa-shimmer {
  0%   { background-position: 100% 50%; }
  100% { background-position: 0 50%; }
}

@media (prefers-reduced-motion: reduce) {
  .skeleton { animation: none; }
}

.spinner {
  display: inline-block;
  width: 1.25em;
  height: 1.25em;
  border: 2px solid var(--color-border-strong);
  border-top-color: var(--color-primary);
  border-radius: 50%;
  animation: noa-spin 0.7s linear infinite;
}

/* ==========================================================================
   12. BRAND PATTERN
   The Greek-key meander taken from the logo lockup. Used sparingly: section
   dividers, footer bands, promotional edges. Never a full-page background.
   ========================================================================== */

.pattern-band {
  height: 24px;
  background-image: var(--pattern-meander);
  background-size: var(--pattern-size);
  background-repeat: repeat-x;
  background-position: center;
}

/* On blue: the motif is white at low opacity. */
.pattern-band-inverse {
  filter: brightness(0) invert(1);
  opacity: 0.35;
}

/* Decorative wash behind a section. Sits under the content, never over it. */
.pattern-wash {
  position: relative;
  isolation: isolate;
}

.pattern-wash::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: var(--z-below);
  background-image: var(--pattern-meander);
  background-size: var(--pattern-size);
  opacity: var(--pattern-opacity);
  pointer-events: none;
}

/* Thin brand rule: blue with a yellow leading segment, echoing the logo bar. */
.rule-brand {
  height: 4px;
  border: 0;
  margin: 0;
  border-radius: var(--radius-full);
  background: linear-gradient(
    to right,
    var(--color-accent) 0 64px,
    var(--color-primary) 64px 100%
  );
}

/* ==========================================================================
   13. SURFACES
   ========================================================================== */

.surface {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
}

.surface-accent {
  background: var(--color-accent);
  color: var(--color-on-accent);
  border-color: transparent;
}

.surface-primary {
  background: var(--color-primary);
  color: var(--color-on-primary);
  border-color: transparent;
}

.surface-sunken {
  background: var(--color-surface-sunken);
  border-color: transparent;
}

/* Definition list used for order summaries and totals. */
.summary-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  padding-block: var(--space-2);
}

.summary-row + .summary-row {
  border-top: var(--border-width) solid var(--color-border);
}

.summary-total {
  font-family: var(--font-heading);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--color-text-strong);
}

/* ==========================================================================
   14. TABLES
   ========================================================================== */

.table-wrap {
  overflow-x: auto;
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

.table th,
.table td {
  padding: var(--space-3) var(--space-4);
  text-align: left;
  vertical-align: middle;
}

.table thead th {
  background: var(--color-surface-sunken);
  font-family: var(--font-heading);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--color-text-muted);
  white-space: nowrap;
}

.table tbody tr + tr {
  border-top: var(--border-width) solid var(--color-border);
}

.table tbody tr:hover {
  background: var(--color-surface-alt);
}

.table .numeric {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
