/* ==========================================================================
   Bongeeo components
   Buttons, forms, cards, badges, modals and the other reusable UI pieces.
   Composed entirely from the tokens in design-system.css.
   ========================================================================== */

/* ==========================================================================
   Buttons
   ========================================================================== */

.btn {
  --btn-bg: transparent;
  --btn-fg: var(--text-primary);
  --btn-border: transparent;
  --btn-bg-hover: transparent;

  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--btn-pad-y, 0.7rem) var(--btn-pad-x, 1.35rem);

  /* 44px keeps every button within the recommended touch target size. */
  min-height: 44px;

  font-size: var(--text-base);
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.01em;
  text-align: center;
  white-space: nowrap;

  color: var(--btn-fg);
  background: var(--btn-bg);
  border: 1.5px solid var(--btn-border);
  border-radius: var(--radius-md);
  cursor: pointer;

  transition:
    background-color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out),
    color var(--duration-fast) var(--ease-out),
    transform var(--duration-fast) var(--ease-out),
    box-shadow var(--duration-fast) var(--ease-out);
}

.btn:hover:not(:disabled) {
  background: var(--btn-bg-hover);
  color: var(--btn-fg);
}

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

.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
  transform: none;
}

.btn--primary {
  --btn-bg: var(--brand-600);
  --btn-bg-hover: var(--brand-700);
  --btn-fg: var(--text-inverse);
  --btn-border: var(--brand-600);
  box-shadow: var(--shadow-sm);
}

.btn--primary:hover:not(:disabled) {
  --btn-border: var(--brand-700);
  box-shadow: var(--shadow-brand);
}

.btn--accent {
  --btn-bg: var(--accent-500);
  --btn-bg-hover: var(--accent-600);
  --btn-fg: var(--text-inverse);
  --btn-border: var(--accent-500);
  box-shadow: var(--shadow-sm);
}

.btn--secondary {
  --btn-bg: var(--surface);
  --btn-bg-hover: var(--ink-50);
  --btn-fg: var(--ink-800);
  --btn-border: var(--border-strong);
}

.btn--ghost {
  --btn-bg: transparent;
  --btn-bg-hover: var(--ink-100);
  --btn-fg: var(--ink-700);
  --btn-border: transparent;
}

.btn--outline-brand {
  --btn-bg: transparent;
  --btn-bg-hover: var(--brand-50);
  --btn-fg: var(--brand-700);
  --btn-border: var(--brand-600);
}

.btn--danger {
  --btn-bg: var(--danger-600);
  --btn-bg-hover: var(--danger-700);
  --btn-fg: var(--text-inverse);
  --btn-border: var(--danger-600);
}

.btn--inverse {
  --btn-bg: var(--surface);
  --btn-bg-hover: var(--ink-100);
  --btn-fg: var(--ink-900);
  --btn-border: var(--surface);
}

.btn--sm {
  --btn-pad-y: 0.45rem;
  --btn-pad-x: 0.9rem;
  min-height: 36px;
  font-size: var(--text-sm);
}

.btn--lg {
  --btn-pad-y: 0.95rem;
  --btn-pad-x: 2rem;
  min-height: 52px;
  font-size: var(--text-md);
}

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

.btn--icon {
  --btn-pad-x: 0;
  width: 44px;
  min-width: 44px;
  padding: 0;
}

.btn--icon.btn--sm {
  width: 36px;
  min-width: 36px;
}

/* Spinner shown while an async action is in flight. */
.btn[data-loading="true"] {
  pointer-events: none;
  position: relative;
  color: transparent !important;
}

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

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

/* ==========================================================================
   Forms
   ========================================================================== */

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

.field__label {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink-700);
}

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

.field__hint {
  font-size: var(--text-xs);
  color: var(--text-muted);
}

.field__error {
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--danger-600);
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

.input,
.select,
.textarea {
  width: 100%;
  padding: 0.7rem 0.9rem;
  min-height: 44px;
  font-size: var(--text-base);
  color: var(--text-primary);
  background: var(--surface);
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius-md);
  transition:
    border-color var(--duration-fast) var(--ease-out),
    box-shadow var(--duration-fast) var(--ease-out);
}

.input::placeholder,
.textarea::placeholder {
  color: var(--ink-400);
}

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

.input:focus,
.select:focus,
.textarea:focus {
  outline: none;
  border-color: var(--brand-600);
  box-shadow: 0 0 0 3px rgba(18, 131, 108, 0.14);
}

.input[aria-invalid="true"],
.select[aria-invalid="true"],
.textarea[aria-invalid="true"],
.input.input-validation-error,
.textarea.input-validation-error,
.select.input-validation-error {
  border-color: var(--danger-500);
}

.input[aria-invalid="true"]:focus,
.input.input-validation-error:focus {
  box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.14);
}

.textarea {
  min-height: 120px;
  resize: vertical;
  line-height: var(--leading-normal);
}

.select {
  appearance: none;
  padding-inline-end: 2.5rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.85rem center;
}

.input-group {
  display: flex;
  align-items: stretch;
}

.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;
}

/* Custom checkbox and radio that stay legible and hit-friendly. */
.checkbox,
.radio {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  cursor: pointer;
  font-size: var(--text-base);
  line-height: 1.4;
  padding-block: var(--space-1);
}

.checkbox input,
.radio input {
  appearance: none;
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  margin: 0;
  margin-block-start: 1px;
  border: 1.5px solid var(--border-strong);
  background: var(--surface);
  cursor: pointer;
  transition:
    background-color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out);
}

.checkbox input {
  border-radius: var(--radius-xs);
}

.radio input {
  border-radius: 50%;
}

.checkbox input:checked,
.radio input:checked {
  background-color: var(--brand-600);
  border-color: var(--brand-600);
}

.checkbox input:checked {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='white' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 8.5l3.5 3.5L13 5'/%3E%3C/svg%3E");
  background-size: 14px;
  background-position: center;
  background-repeat: no-repeat;
}

.radio input:checked {
  box-shadow: inset 0 0 0 4px var(--surface);
}

.checkbox input:focus-visible,
.radio input:focus-visible {
  outline: 2px solid var(--brand-600);
  outline-offset: 2px;
}

/* Validation summary emitted by ASP.NET Core. */
.validation-summary-errors {
  padding: var(--space-4);
  background: var(--danger-50);
  border: 1px solid rgba(239, 68, 68, 0.28);
  border-radius: var(--radius-md);
  color: var(--danger-700);
  font-size: var(--text-sm);
}

.validation-summary-errors ul {
  margin: 0;
  padding-inline-start: var(--space-5);
}

.validation-summary-valid {
  display: none;
}

.field-validation-error {
  display: block;
  margin-block-start: var(--space-1);
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--danger-600);
}

/* ==========================================================================
   Cards
   ========================================================================== */

.card {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition:
    border-color var(--duration-base) var(--ease-out),
    box-shadow var(--duration-base) var(--ease-out),
    transform var(--duration-base) var(--ease-out);
}

.card--interactive:hover {
  border-color: var(--border-strong);
  box-shadow: var(--shadow-lg);
  transform: translateY(-3px);
}

.card__body {
  padding: var(--space-5);
}

.card__header {
  padding: var(--space-5);
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

.card__footer {
  padding: var(--space-4) var(--space-5);
  border-top: 1px solid var(--border);
  background: var(--surface-sunken);
}

/* ==========================================================================
   Badges and pills
   ========================================================================== */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
  padding: 0.3em 0.65em;
  font-size: var(--text-2xs);
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  border-radius: var(--radius-sm);
  white-space: nowrap;
}

.badge--new { background: var(--info-50); color: var(--info-700); }
.badge--sale { background: var(--danger-50); color: var(--danger-700); }
.badge--hot { background: #fff1e6; color: var(--accent-600); }
.badge--bestseller { background: var(--warning-50); color: var(--warning-700); }
.badge--trending { background: #f3e8ff; color: #7e22ce; }
.badge--featured { background: var(--brand-50); color: var(--brand-700); }
.badge--limited { background: var(--danger-50); color: var(--danger-700); }
.badge--freeship { background: var(--success-50); color: var(--success-700); }
.badge--exclusive { background: var(--ink-900); color: #fff; }
.badge--neutral { background: var(--ink-100); color: var(--ink-700); }
.badge--success { background: var(--success-50); color: var(--success-700); }
.badge--warning { background: var(--warning-50); color: var(--warning-700); }
.badge--danger { background: var(--danger-50); color: var(--danger-700); }
.badge--info { background: var(--info-50); color: var(--info-700); }

.badge--discount {
  background: var(--danger-600);
  color: #fff;
  font-size: var(--text-xs);
  padding: 0.35em 0.6em;
  border-radius: var(--radius-sm);
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0.4rem 0.85rem;
  font-size: var(--text-sm);
  font-weight: 500;
  background: var(--ink-100);
  color: var(--ink-700);
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  transition: all var(--duration-fast) var(--ease-out);
}

.pill--removable {
  padding-inline-end: 0.4rem;
}

.pill__remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border: 0;
  border-radius: 50%;
  background: rgba(15, 23, 42, 0.1);
  color: inherit;
  cursor: pointer;
  font-size: 12px;
  line-height: 1;
}

.pill__remove:hover {
  background: var(--danger-500);
  color: #fff;
}

/* ==========================================================================
   Alerts and toasts
   ========================================================================== */

.alert {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  font-size: var(--text-base);
  line-height: var(--leading-snug);
}

.alert__icon {
  flex-shrink: 0;
  font-size: 1.15em;
  margin-block-start: 1px;
}

.alert--success { background: var(--success-50); border-color: rgba(16, 185, 129, 0.28); color: var(--success-700); }
.alert--warning { background: var(--warning-50); border-color: rgba(245, 158, 11, 0.28); color: var(--warning-700); }
.alert--danger { background: var(--danger-50); border-color: rgba(239, 68, 68, 0.28); color: var(--danger-700); }
.alert--info { background: var(--info-50); border-color: rgba(59, 130, 246, 0.28); color: var(--info-700); }

.toast-region {
  position: fixed;
  inset-block-end: calc(var(--space-6) + var(--safe-bottom));
  inset-inline-end: var(--space-6);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);

  /* Percentages resolve against the viewport for a fixed element, and unlike
     `100vw` they exclude the scrollbar — so this can never cause a sideways
     scroll on desktop. */
  max-width: min(380px, calc(100% - var(--space-8)));

  /* The region must not block clicks; individual toasts re-enable them. */
  pointer-events: none;
}

/* On phones the bottom-right corner already belongs to the floating WhatsApp
   and call buttons, and to the sticky buy bar on a product page. Toasts move
   under the header instead of stacking on top of controls the customer is
   trying to press. */
@media (max-width: 640px) {
  .toast-region {
    inset-block: calc(var(--header-height) + var(--space-3)) auto;
    inset-inline: var(--space-4);
    max-width: none;
  }
}

.toast {
  pointer-events: auto;
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-inline-start: 4px solid var(--brand-600);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  animation: toast-in var(--duration-base) var(--ease-spring);
}

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

.toast[data-leaving="true"] {
  animation: toast-out var(--duration-base) var(--ease-out) forwards;
}

@keyframes toast-in {
  from { opacity: 0; transform: translateX(24px) scale(0.96); }
  to { opacity: 1; transform: translateX(0) scale(1); }
}

@keyframes toast-out {
  to { opacity: 0; transform: translateX(24px) scale(0.96); }
}

/* ==========================================================================
   Modal and drawer
   ========================================================================== */

.modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: grid;
  place-items: center;
  padding: var(--space-4);
  background: rgba(15, 23, 42, 0.55);
  backdrop-filter: blur(3px);
  animation: fade-in var(--duration-base) var(--ease-out);
}

.modal[hidden] {
  display: none;
}

.modal__panel {
  width: 100%;
  max-width: var(--modal-width, 640px);
  max-height: min(88svh, 900px);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--surface-raised);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-xl);
  animation: modal-in var(--duration-base) var(--ease-spring);
}

.modal__header {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5);
  background: var(--surface-raised);
  border-bottom: 1px solid var(--border);
}

.modal__body { padding: var(--space-5); }

.modal__footer {
  position: sticky;
  bottom: 0;
  display: flex;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  background: var(--surface-raised);
  border-top: 1px solid var(--border);
}

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

@keyframes modal-in {
  from { opacity: 0; transform: translateY(20px) scale(0.97); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

.drawer {
  position: fixed;
  inset: 0;
  z-index: var(--z-drawer);
  background: rgba(15, 23, 42, 0.5);
  animation: fade-in var(--duration-base) var(--ease-out);
}

.drawer[hidden] { display: none; }

.drawer__panel {
  position: absolute;
  inset-block: 0;
  inset-inline-end: 0;

  /* `100%` rather than `100vw`: the latter includes the scrollbar width and
     pushes the panel a few pixels off screen on desktop. */
  width: min(420px, 100%);
  display: flex;
  flex-direction: column;
  background: var(--surface-raised);
  box-shadow: var(--shadow-xl);
  animation: drawer-in var(--duration-base) var(--ease-out);
}

.drawer--start .drawer__panel {
  inset-inline-end: auto;
  inset-inline-start: 0;
  animation-name: drawer-in-start;
}

.drawer__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-5);
  border-bottom: 1px solid var(--border);
}

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

  /* Prevents the page behind from scrolling when this reaches its end. */
  overscroll-behavior: contain;
}

.drawer__footer {
  padding: var(--space-5);
  border-top: 1px solid var(--border);
  background: var(--surface-sunken);
}

@keyframes drawer-in {
  from { transform: translateX(100%); }
  to { transform: translateX(0); }
}

@keyframes drawer-in-start {
  from { transform: translateX(-100%); }
  to { transform: translateX(0); }
}

/* ==========================================================================
   Tabs and accordion
   ========================================================================== */

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

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

.tab {
  padding: var(--space-3) var(--space-5);
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--text-muted);
  background: none;
  border: 0;
  border-bottom: 2.5px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  transition: all var(--duration-fast) var(--ease-out);
}

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

.tab[aria-selected="true"] {
  color: var(--brand-700);
  border-bottom-color: var(--brand-600);
}

.tab-panel[hidden] { display: none; }

.accordion__item {
  border-bottom: 1px solid var(--border);
}

.accordion__trigger {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5) 0;
  font-size: var(--text-md);
  font-weight: 600;
  text-align: start;
  color: var(--ink-800);
  background: none;
  border: 0;
  cursor: pointer;
  transition: color var(--duration-fast) var(--ease-out);
}

.accordion__trigger:hover { color: var(--brand-700); }

.accordion__icon {
  flex-shrink: 0;
  transition: transform var(--duration-base) var(--ease-out);
}

.accordion__trigger[aria-expanded="true"] .accordion__icon {
  transform: rotate(180deg);
}

/* Animating grid-template-rows gives a smooth open without a fixed height. */
.accordion__content {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--duration-base) var(--ease-out);
}

.accordion__content[data-open="true"] {
  grid-template-rows: 1fr;
}

.accordion__content > div {
  overflow: hidden;
}

.accordion__content .accordion__inner {
  padding-block-end: var(--space-5);
  color: var(--text-secondary);
  line-height: var(--leading-relaxed);
}

/* ==========================================================================
   Rating stars
   ========================================================================== */

.rating {
  display: inline-flex;
  align-items: center;
  gap: 1px;
  color: var(--accent-500);
  font-size: 0.95em;
  line-height: 1;
}

.rating--muted { color: var(--ink-300); }

.rating__count {
  margin-inline-start: var(--space-2);
  font-size: var(--text-xs);
  color: var(--text-muted);
}

/* ==========================================================================
   Quantity stepper
   ========================================================================== */

.quantity {
  display: inline-flex;
  align-items: stretch;
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--surface);
}

.quantity__btn {
  width: 42px;
  min-height: 42px;
  display: grid;
  place-items: center;
  border: 0;
  background: var(--surface);
  color: var(--ink-700);
  cursor: pointer;
  font-size: 1.1rem;
  transition: background-color var(--duration-fast) var(--ease-out);
}

.quantity__btn:hover:not(:disabled) { background: var(--ink-100); }
.quantity__btn:disabled { opacity: 0.4; cursor: not-allowed; }

.quantity__input {
  width: 52px;
  border: 0;
  border-inline: 1.5px solid var(--border-strong);
  text-align: center;
  font-weight: 600;
  font-size: var(--text-base);

  /* Number spinners duplicate the buttons either side. */
  appearance: textfield;
}

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

.quantity__input:focus { outline: none; background: var(--brand-50); }

/* ==========================================================================
   Breadcrumbs and pagination
   ========================================================================== */

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

.breadcrumbs a { color: var(--text-muted); }
.breadcrumbs a:hover { color: var(--brand-700); }

.breadcrumbs li:not(:last-child)::after {
  content: "/";
  margin-inline-start: var(--space-2);
  color: var(--ink-300);
}

.breadcrumbs [aria-current="page"] {
  color: var(--ink-800);
  font-weight: 500;
}

.pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
}

.pagination__link {
  display: grid;
  place-items: center;
  min-width: 42px;
  height: 42px;
  padding-inline: var(--space-3);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink-700);
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-md);
  transition: all var(--duration-fast) var(--ease-out);
}

.pagination__link:hover {
  border-color: var(--brand-500);
  color: var(--brand-700);
}

.pagination__link[aria-current="page"] {
  background: var(--brand-600);
  border-color: var(--brand-600);
  color: var(--text-inverse);
}

.pagination__link[aria-disabled="true"] {
  opacity: 0.4;
  pointer-events: none;
}

/* ==========================================================================
   Skeleton loading
   ========================================================================== */

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

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

/* ==========================================================================
   Empty state
   ========================================================================== */

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

.empty-state__icon {
  display: grid;
  place-items: center;
  width: 76px;
  height: 76px;
  font-size: 2rem;
  color: var(--ink-400);
  background: var(--ink-100);
  border-radius: 50%;
}

.empty-state__title {
  font-size: var(--text-lg);
  font-weight: 650;
  color: var(--ink-800);
}

/* ==========================================================================
   Section heading
   ========================================================================== */

.section-heading {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
  margin-block-end: var(--space-8);
}

/* For sections whose content is a symmetrical row rather than a list with a
   trailing action, so a left-aligned heading would sit off-balance. */
.section-heading--center {
  justify-content: center;
  text-align: center;
}

.section-heading--center .section-heading__subtitle {
  margin-inline: auto;
}

.section-heading__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-block-end: var(--space-2);
  color: var(--brand-700);
}

.section-heading__title {
  position: relative;
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 600;
  color: var(--ink-900);
}

/* A short brand rule above the title. It costs one pseudo-element and gives
   every section the same opening mark, which is what makes a long page read as
   a sequence of deliberate sections rather than a stack of headings. */
.section-heading__title::before {
  content: "";
  display: block;
  width: 44px;
  height: 3px;
  margin-block-end: var(--space-3);
  background: linear-gradient(90deg, var(--brand-500), var(--accent-400));
  border-radius: var(--radius-pill);
}

.section-heading--center .section-heading__title::before {
  margin-inline: auto;
}

/* The eyebrow already carries the opening mark when one is present. */
.section-heading__eyebrow + .section-heading__title::before {
  display: none;
}

.section-heading__subtitle {
  margin-block-start: var(--space-2);
  font-size: var(--text-md);
  color: var(--text-secondary);
  max-width: 60ch;
}

/* ==========================================================================
   Scroll reveal

   `data-reveal` is only ever set by the script, and only when the reader has
   not asked for reduced motion — so this rule cannot hide anything that has no
   way to be un-hidden. See initScrollReveal.
   ========================================================================== */

[data-reveal] {
  opacity: 0;
  transform: translate3d(0, 26px, 0);
  transition:
    opacity 700ms var(--ease-out),
    transform 700ms var(--ease-out);
}

[data-reveal][data-revealed="true"] {
  opacity: 1;
  transform: none;
}

/* ==========================================================================
   Promotional cards — the offers row on the home page

   The picture sits in its own panel beside the copy rather than behind it, so
   text never covers the product and the photograph can be shown whole. Because
   an administrator can upload any shape of image, the panel is built to take
   any aspect ratio: the picture is contained, and a blurred copy of it fills
   whatever space that leaves.
   ========================================================================== */

.promo-card {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 44%) minmax(0, 1fr);
  min-height: 280px;
  overflow: hidden;
  color: var(--promo-ink, #fff);
  background: var(--promo-bg, var(--ink-800));
  border-radius: var(--radius-lg);
  transition:
    box-shadow var(--duration-base) var(--ease-out),
    transform var(--duration-base) var(--ease-out);
}

.promo-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lg);
}

.promo-card:focus-visible {
  outline: 3px solid var(--brand-500);
  outline-offset: 3px;
}

/* No artwork at all: the copy takes the whole card, lifted by a soft highlight
   so it does not read as a flat block of colour. */
.promo-card--plain {
  grid-template-columns: minmax(0, 1fr);
}

.promo-card--plain::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 90% at 78% 18%, rgba(255, 255, 255, 0.22), transparent 62%),
    radial-gradient(80% 70% at 10% 100%, rgba(0, 0, 0, 0.28), transparent 70%);
}

.promo-card__figure {
  position: relative;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.18);
}

/* Blurred and over-scaled so no hard edge of the copy shows at the panel border. */
.promo-card__fill {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: blur(22px) saturate(1.2);
  transform: scale(1.25);
  opacity: 0.55;
}

/* `contain`, never `cover`: the whole photograph has to be visible, whatever
   shape it was uploaded in. */
.promo-card__image {
  position: relative;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  transition: transform var(--duration-slow, 500ms) var(--ease-out);
}

/* Vector artwork is decorative rather than a product, so it may fill the panel. */
.promo-card__figure--art .promo-card__image {
  object-fit: cover;
}

.promo-card:hover .promo-card__image {
  transform: scale(1.04);
}

.promo-card__body {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-6);
}

.promo-card__offer {
  display: inline-flex;
  align-items: center;
  padding: 0.3rem 0.7rem;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: inherit;
  background: rgba(255, 255, 255, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: var(--radius-pill);
}

.promo-card__title {
  margin: 0;
  font-size: var(--text-xl);
  line-height: 1.2;
  color: inherit;
  text-wrap: balance;
}

.promo-card__text {
  margin: 0;
  font-size: var(--text-sm);
  color: inherit;
  opacity: 0.86;

  /* Keeps a single word from being left alone on the last line. */
  text-wrap: pretty;
}

.promo-card__cta {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-block-start: var(--space-2);
  padding-block-end: 2px;
  font-size: var(--text-sm);
  font-weight: 600;
  color: inherit;
  border-bottom: 1.5px solid rgba(255, 255, 255, 0.45);
}

.promo-card__cta i {
  transition: transform var(--duration-fast) var(--ease-out);
}

.promo-card:hover .promo-card__cta i {
  transform: translateX(3px);
}

/* On a narrow phone the two columns leave the copy too tight, so the picture
   moves above it and takes a landscape box of its own. */
@media (max-width: 420px) {
  .promo-card {
    grid-template-columns: minmax(0, 1fr);
    min-height: 0;
  }

  /* 4:3 rather than a wide strip: product photography is portrait, so a taller
     box lets the contained picture render larger. */
  .promo-card__figure {
    aspect-ratio: 4 / 3;
  }
}

@media (prefers-reduced-motion: reduce) {
  .promo-card,
  .promo-card__image,
  .promo-card__cta i {
    transition: none;
  }

  .promo-card:hover,
  .promo-card:hover .promo-card__image,
  .promo-card:hover .promo-card__cta i {
    transform: none;
  }
}

/* ==========================================================================
   Paged rails — product and review sections on the home and product pages

   These used to be horizontal scrollers. They now page instead, so a section
   never introduces a sideways scrollbar and every item is reachable through a
   numbered control rather than by dragging.
   ========================================================================== */

/* Cards inside a rail set their own `display` (product cards and testimonials are
   both flex columns), and an author `display` beats the browser's built-in
   [hidden] rule. Without this the script marks off-page items hidden and they
   carry on rendering, so the rail looks unpaginated. The child combinator keeps
   the specificity above the card classes without reaching for !important. */
[data-rail] > [hidden] {
  display: none;
}

.rail-pagination {
  margin-block-start: var(--space-6);
}

/* Same reasoning: .pagination is display:flex, so a one-page rail would show an
   empty control strip rather than nothing. */
.rail-pagination[hidden] {
  display: none;
}

/* Cursor and font are set explicitly: these are <button> elements borrowing the
   pagination styling, which was written for links. */
.rail-pagination .pagination__link {
  font-family: inherit;
  cursor: pointer;
}

.rail-pagination .pagination__link:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* On the flash sale's dark ground the default surface colours disappear. */
.rail-pagination--inverse .pagination__link {
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.28);
  color: #fff;
}

.rail-pagination--inverse .pagination__link:hover {
  background: rgba(255, 255, 255, 0.22);
  border-color: rgba(255, 255, 255, 0.5);
  color: #fff;
}

.rail-pagination--inverse .pagination__link[aria-current="page"] {
  background: #fff;
  border-color: #fff;
  color: var(--ink-900);
}

.scroller-controls {
  display: none;
  gap: var(--space-2);
}

@media (min-width: 900px) {
  .scroller-controls { display: flex; }
}

.scroller-controls[hidden] { display: none; }

/* ==========================================================================
   Tables
   ========================================================================== */

.table-wrap {
  overflow-x: auto;

  /* Keeps a sideways swipe inside the table instead of triggering the
     browser's back gesture once it reaches the end. */
  overscroll-behavior-x: contain;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
}

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

.table th {
  padding: var(--space-3) var(--space-4);
  text-align: start;
  font-weight: 650;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--text-muted);
  background: var(--surface-sunken);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

.table td {
  padding: var(--space-4);
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}

.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr:hover { background: var(--surface-sunken); }

.table--compact td,
.table--compact th { padding: var(--space-2) var(--space-3); }

.table__numeric {
  text-align: end;
  font-variant-numeric: tabular-nums;
}

/* Phones: buy back horizontal room so fewer columns fall off the edge, and
   stop the pagination and section headings from crowding. */
@media (max-width: 640px) {
  .table th,
  .table td {
    padding: var(--space-3);
  }

  .card__body,
  .card__header,
  .modal__body,
  .modal__header,
  .drawer__body,
  .drawer__header,
  .drawer__footer {
    padding: var(--space-4);
  }

  .empty-state {
    padding-block: var(--space-10);
  }

  .section-heading {
    margin-block-end: var(--space-6);
  }
}

/* ==========================================================================
   Interaction polish

   Additive refinements layered over the primitives above rather than folded
   into them, so the base components keep their single definition and this pass
   can be read — or removed — as one piece. Everything here is a hover, focus
   or press response: nothing changes resting layout, so nothing here can shift
   the page or affect what a reader without a pointer sees.
   ========================================================================== */

/* A call to action should feel like it lifts under the cursor and takes the
   press. The base button already darkens on hover; this adds the physical part. */
.btn--primary:hover:not(:disabled),
.btn--accent:hover:not(:disabled),
.btn--danger:hover:not(:disabled) {
  transform: translateY(-2px);
}

.btn--primary:active:not(:disabled),
.btn--accent:active:not(:disabled),
.btn--danger:active:not(:disabled) {
  transform: translateY(0);
  box-shadow: var(--shadow-xs);
}

.btn--accent:hover:not(:disabled) {
  box-shadow: 0 10px 24px rgba(224, 127, 44, 0.32);
}

/* The arrow in a "view all" or "shop now" control leads the eye to where the
   click goes. */
.btn .bi-arrow-right {
  transition: transform var(--duration-base) var(--ease-out);
}

.btn:hover:not(:disabled) .bi-arrow-right {
  transform: translateX(3px);
}

/* Product tiles: the picture is fitted rather than cropped, so a scale on
   hover reads as the garment stepping forward instead of the frame zooming. */
.product-card:hover .product-card__image--primary,
.product-card:hover .product-card__image--secondary {
  transform: scale(1.04);
}

.product-card:focus-within {
  border-color: var(--border-strong);
  box-shadow: var(--shadow-lg);
}

/* Discounts are the one badge that should read before the picture does. */
.badge--discount {
  box-shadow: 0 4px 10px rgba(185, 28, 28, 0.28);
}

/* Fields settle into focus rather than snapping, and the ring is the brand's. */
.input,
.select,
.textarea {
  transition:
    border-color var(--duration-fast) var(--ease-out),
    box-shadow var(--duration-fast) var(--ease-out),
    background-color var(--duration-fast) var(--ease-out);
}

.input:focus,
.select:focus,
.textarea:focus {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-500) 22%, transparent);
}

/* Footer links get the same underline growth the navigation uses, so the two
   ends of the page behave alike. */
.site-footer a:not(.btn) {
  background-image: linear-gradient(currentColor, currentColor);
  background-position: 0 100%;
  background-repeat: no-repeat;
  background-size: 0% 1px;
  transition: background-size var(--duration-base) var(--ease-out);
}

.site-footer a:not(.btn):hover {
  background-size: 100% 1px;
}

@media (prefers-reduced-motion: reduce) {
  .btn--primary:hover:not(:disabled),
  .btn--accent:hover:not(:disabled),
  .btn--danger:hover:not(:disabled),
  .btn:hover:not(:disabled) .bi-arrow-right,
  .product-card:hover .product-card__image--primary,
  .product-card:hover .product-card__image--secondary {
    transform: none;
  }
}
