/**
 * The hand-written half of the stylesheet.
 *
 * Everything here is written once and read by every page: the reset, the
 * design tokens, the two typefaces, and the handful of rules that cannot be
 * expressed as a utility. The other half — the utilities themselves — is
 * generated from the templates by `bin/build-css.php` and appended below this.
 *
 * The tokens and their names match the Professional Edition exactly, because
 * both editions are the same product and a merchant moving between them should
 * not be able to tell which one they are looking at.
 */

/* ------------------------------------------------------------------- typefaces
 *
 * Both families are served from this host. Nothing is fetched from a third
 * party: no extra DNS lookup, no request an ISP can block, and no record with
 * anybody else of who is reading the shop.
 *
 * `swap` so text is readable immediately in the fallback and re-renders when
 * the real face lands — a blank paragraph for 300ms reads as a broken page.
 */

/*
 * IRANSans — the Persian face.
 *
 * Only 400 and 700 exist. Nothing asks for another weight, and a browser
 * synthesising a missing one produces the smeared fake-bold that makes Persian
 * text look broken.
 */
@font-face {
  font-family: 'IRANSans';
  src: url('../fonts/iransans-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'IRANSans';
  src: url('../fonts/iransans-700.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/*
 * Inter — the Latin face, chosen to sit beside IRANSans rather than fight it.
 *
 * Both are neutral humanist sans faces with open apertures and a tall
 * x-height, so a bilingual line does not read as two different documents.
 *
 * One variable file covers every weight, which is why there is a single
 * `@font-face` here against IRANSans's two.
 */
@font-face {
  font-family: 'Inter';
  src: url('../fonts/inter-latin.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* ----------------------------------------------------------------- the tokens
 *
 * Defaults, overwritten by the block the layout injects from the merchant's
 * settings. Present so a page rendered before settings load — an error page,
 * say — is still readable rather than unstyled.
 */
:root {
  --store-primary: #111827;
  --store-primary-contrast: #ffffff;
  --store-accent: #2563eb;
  --store-accent-contrast: #ffffff;

  /*
   * The daytime neutrals: the merchant's choice, or these if they have none.
   *
   * `--shop-*` is what the inline block on <html> sets. The indirection is what
   * makes dark mode possible at all — an inline style outranks every rule here,
   * so a night palette could never override a property the merchant had set
   * directly.
   */
  --store-background: var(--shop-background, #ffffff);
  --store-text: var(--shop-text, #111827);
  --store-muted: var(--shop-muted, #6b7280);
  --store-border: var(--shop-border, #e5e7eb);
  --store-surface: var(--shop-surface, #f9fafb);

  /*
   * The platform's own identity, which dresses the DASHBOARD and nothing else.
   *
   * The storefront's colours belong to whoever owns the shop; these belong to
   * the software. Keeping them in separate namespaces is what stops a
   * merchant's brand choices leaking into the admin, or ours into their shop.
   */
  --brand-primary: #5438fc;
  --brand-accent: #fe9401;
  --brand-ink: #05050c;
  --brand-ink-soft: #12121f;
}

/* ------------------------------------------------------------------ at night
 *
 * The dark palette overrides only the NEUTRALS. The merchant's primary and
 * accent stay exactly as they set them: those are the brand, and a shop whose
 * buttons change colour at dusk is not the same shop.
 *
 * The values are a set, not five independent choices — `surface` sits one step
 * off `background` so a card separates from the page, and `border` sits one
 * step off `surface` for the same reason. Picking them individually is how a
 * dark theme ends up with invisible edges.
 */
@media (prefers-color-scheme: dark) {
  /*
   * Guarded, so a viewer who has explicitly chosen light is not overridden by
   * their system. `data-theme="dark"` below covers the other direction.
   */
  :root:not([data-theme='light']) {
    --store-background: #0b0b0f;
    --store-text: #e8e8ea;
    --store-surface: #16161c;
    --store-border: #2a2a33;
    --store-muted: #9a9aa5;
  }
}

:root[data-theme='dark'] {
  --store-background: #0b0b0f;
  --store-text: #e8e8ea;
  --store-surface: #16161c;
  --store-border: #2a2a33;
  --store-muted: #9a9aa5;
}

/*
 * The browser's own furniture follows.
 *
 * Without this a dark page still gets a white form control, a white scrollbar
 * and a white autofill background — the details that make a dark theme look
 * half-finished rather than dark.
 */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    color-scheme: dark;
  }
}

:root[data-theme='dark'] {
  color-scheme: dark;
}

:root[data-theme='light'] {
  color-scheme: light;
}

/*
 * The toggle shows the theme it will switch TO, not the one in force.
 *
 * A button showing a moon while the page is already dark reads as a state
 * indicator and gets pressed to no effect. Only one of the two glyphs is ever
 * in the document; the other is `display: none`.
 */
.theme-when-dark {
  display: none;
}

:root[data-theme='dark'] .theme-when-dark {
  display: block;
}

:root[data-theme='dark'] .theme-when-light {
  display: none;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .theme-when-dark {
    display: block;
  }

  :root:not([data-theme='light']) .theme-when-light {
    display: none;
  }
}

/* ---------------------------------------------------------------------- reset
 *
 * Small and deliberate. Browser defaults that fight a designed layout are
 * removed; the ones that carry meaning — a list still being a list to a screen
 * reader, a button still being focusable — are left alone.
 */
*,
*::before,
*::after {
  box-sizing: border-box;
  border: 0 solid var(--store-border);
  margin: 0;
  padding: 0;
}

html {
  background-color: var(--store-background);
  color: var(--store-text);
  /*
   * Persian text is taller than Latin at the same size; the extra leading stops
   * descenders from colliding in RTL paragraphs.
   */
  line-height: 1.6;
  -webkit-text-size-adjust: 100%;
  tab-size: 4;
}

body {
  min-height: 100dvh;
  font-family: inherit;
}

/* Headings inherit their scale from a utility, not from the browser. */
h1,
h2,
h3,
h4,
h5,
h6 {
  font-size: inherit;
  font-weight: inherit;
}

a {
  color: inherit;
  text-decoration: inherit;
}

/*
 * Lists lose their markers visually but stay lists structurally.
 *
 * `list-style: none` on its own removes the semantics in Safari with VoiceOver;
 * the explicit `role="list"` in the markup is what puts them back, and this
 * rule is written to match that pairing.
 */
ol,
ul,
menu {
  list-style: none;
}

/*
 * Form controls inherit type instead of falling back to the browser's.
 *
 * Without this an <input> renders in 13px Arial regardless of the page, which
 * is especially wrong for Persian: the field ends up in a Latin face while the
 * label beside it is in IRANSans.
 */
button,
input,
optgroup,
select,
textarea {
  font: inherit;
  color: inherit;
  background: transparent;
  letter-spacing: inherit;
}

button,
[type='button'],
[type='reset'],
[type='submit'] {
  appearance: button;
  cursor: pointer;
}

/* A disabled control should not offer a pointer that promises something. */
button:disabled,
[type='submit']:disabled {
  cursor: default;
}

textarea {
  resize: vertical;
}

::placeholder {
  color: var(--store-muted);
  opacity: 1;
}

/*
 * Replaced elements sit on the text baseline by default, which leaves a few
 * pixels of gap under every image inside a link or a card.
 */
img,
svg,
video,
canvas,
audio,
iframe,
embed,
object {
  display: block;
  vertical-align: middle;
}

img,
video {
  max-width: 100%;
  height: auto;
}

table {
  border-collapse: collapse;
  text-indent: 0;
  border-color: inherit;
}

summary {
  display: list-item;
  cursor: pointer;
}

hr {
  height: 0;
  color: inherit;
  border-top-width: 1px;
}

[hidden] {
  display: none !important;
}

/* ---------------------------------------------------------------------- focus
 *
 * Visible by default and never removed.
 *
 * `:focus-visible` rather than `:focus`, so a mouse click on a button does not
 * leave a ring behind while keyboard navigation still shows one.
 */
:focus-visible {
  outline: 2px solid var(--store-accent);
  outline-offset: 2px;
}

/*
 * Animation is feedback, and a visitor who has asked for less motion gets none.
 *
 * Not merely shortened — cut to a frame, so `transitionend` and `animationend`
 * still fire and nothing waits forever on a callback that never arrives.
 */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ----------------------------------------------------------------- the script
 *
 * The typeface follows the LANGUAGE, not the page.
 *
 * Selecting on `lang` rather than setting one font on <body> means a Persian
 * product name quoted inside an English page still renders in IRANSans — the
 * same places that need `dir` isolation need the right face, and both are
 * driven by the same attribute.
 */
:root:lang(fa),
[lang='fa'] {
  font-family: 'IRANSans', Tahoma, 'Segoe UI', sans-serif;
  /*
   * IRANSans sits slightly small next to Inter at the same nominal size, which
   * reads as a Persian page being quieter than its English twin. A hair of
   * extra size and leading evens them out.
   */
  font-size: 1.02em;
  line-height: 1.75;
}

:root:lang(en),
[lang='en'] {
  font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
}

/* ------------------------------------------------------------------ animation
 *
 * The two keyframes the utilities reference. Everything else that moves is a
 * transition, which needs no declaration.
 */
@keyframes cms-spin {
  to {
    rotate: 360deg;
  }
}

@keyframes cms-pulse {
  50% {
    opacity: 0.5;
  }
}

/* ------------------------------------------------------------- footer palette
 *
 * The footer's own light and dark, independent of the page above it.
 *
 * Every other surface on this storefront follows the visitor's theme. The
 * footer is the one place a merchant routinely wants the opposite: a black slab
 * under a white page is a deliberate, everyday design. Before this the only way
 * to reach for it was a hex value in `footer_background`, which moved the
 * BACKGROUND and left the text, the links, the rules and the icons still
 * coloured for a white page — dark grey on black.
 *
 * So the footer aliases the page's colours into a `--footer-*` set of its own
 * and every rule inside it reads that set instead. Three consequences worth the
 * indirection:
 *
 *  - `auto` is a pure alias, so it costs nothing and cannot drift from the page.
 *  - Pinning the footer is five variable values, not a duplicate set of rules.
 *  - A future third palette is one more block here, and no template changes.
 */
.shop-footer {
  /*
   * `auto`: whatever the page is. Aliases, not copies — a visitor switching to
   * dark mode moves the footer with the page and this scope adds nothing.
   *
   * The background stays transparent because that is what a footer with no
   * chosen palette has always looked like, and a migration must not repaint an
   * installed shop.
   */
  --footer-bg: transparent;
  --footer-text: var(--store-text);
  --footer-muted: var(--store-muted);
  --footer-border: var(--store-border);
  --footer-surface: var(--store-surface);

  /*
   * The heavier of the two edges.
   *
   * The brand card is outlined and the copyright is merely ruled off; drawing
   * both at one weight loses the difference between a container and a divider.
   */
  --footer-line: var(--store-border);

  color: var(--footer-text);
}

/*
 * A card needs a surface to be a card.
 *
 * The band has no background of its own, but the same transparency in a rounded
 * card leaves a floating rectangle of nothing. One step off the page is what
 * makes the shape read.
 */
.shop-footer.is-card {
  --footer-bg: var(--store-surface);
}

/*
 * Pinned dark, whatever the page is doing.
 *
 * The five values are written out rather than pointing at the page's night
 * palette: this footer must NOT move when the visitor switches theme, which is
 * the whole reason for choosing it over `auto`.
 *
 * The edges are translucent white rather than the page's flat `#2a2a33`, so
 * they hold their relationship to the background if a merchant also sets a
 * `footer_background` of their own — a fixed grey line on an unexpected colour
 * is how a border ends up brighter than the thing it surrounds.
 *
 * These sit AFTER `.is-card` at equal specificity and win by order, which is
 * what makes a pinned palette outrank the shape's default.
 */
.shop-footer[data-scheme='dark'] {
  --footer-bg: #0b0b0f;
  --footer-text: #e8e8ea;
  --footer-muted: #9a9aa5;
  --footer-border: rgba(255, 255, 255, 0.2);
  --footer-surface: #16161c;
  --footer-line: rgba(255, 255, 255, 0.4);
}

.shop-footer[data-scheme='light'] {
  --footer-bg: #ffffff;
  --footer-text: #111827;
  --footer-muted: #6b7280;
  --footer-border: rgba(0, 0, 0, 0.12);
  --footer-surface: #f9fafb;
  --footer-line: rgba(0, 0, 0, 0.25);
}

/* ----------------------------------------------------------------- its shape
 *
 * Two shapes, chosen by the layout rather than by a setting of their own: the
 * grid is a band across the foot of the page, and the centred stack is a card.
 *
 * The card is the shape that makes a pinned palette look intentional. A dark
 * band bleeding to all four edges reads as the page having ended; a dark card
 * inset from the margin reads as a panel somebody placed there.
 */
.shop-footer--band {
  background-color: var(--footer-bg);
  border-top: 1px solid var(--footer-border);
}

.shop-footer-card {
  background-color: var(--footer-bg);

  /*
   * 32px, and it does not grow with the viewport.
   *
   * A radius in relative units looks correct at one width and like a lozenge at
   * another. This is a fixed corner on a box that changes width, which is how
   * the shape stays recognisably the same on a phone and on a desktop.
   */
  border-radius: 32px;
  padding: 2rem 1.5rem 1.25rem;

  /*
   * Nothing inside a rounded box may square off its corners — an image or a
   * badge reaching the edge would otherwise cut through the radius.
   */
  overflow: hidden;
}

@media (min-width: 640px) {
  .shop-footer-card {
    padding: 3rem 3rem 1.75rem;
  }
}

/*
 * The copyright line.
 *
 * The MONO face and the tracking belong to the year alone, not to the whole
 * line. Persian is a joined script: letter-spacing pulls the letters of a shop
 * name apart into disconnected glyphs, and a monospace family usually has no
 * Arabic shaping to fall back on, so a name set this way renders as six loose
 * characters where the shop's name should be.
 *
 * So the line keeps the page's own face and only the `<bdi>` holding the
 * copyright symbol and the year — always Latin, whatever the shop's language —
 * gets the stamped treatment.
 */
.footer-copyright {
  font-size: 0.6875rem;
  color: var(--footer-text);
}

.footer-copyright :where(bdi) {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  letter-spacing: 0.05em;
}

/* ------------------------------------------------------------------- the FAQ
 *
 * `<details>` gives the open and closed states, the keyboard behaviour, the
 * announcement that a region expands, and finding text inside a closed answer
 * with the browser's own search. All of it free, none of it needing a line of
 * JavaScript — which is why the section is built on it.
 *
 * Everything below is presentation over that. Nothing here is required for the
 * accordion to work: with this file missing it is still a list of questions
 * that open.
 */
/*
 * The small label over the heading.
 *
 * Wide tracking and upper case are a LATIN treatment. Persian is a joined
 * script — tracking pulls its letters apart, the same way it mangled the shop's
 * name in the footer's copyright line — and it has no upper case to make. So
 * both are undone when the page is set right to left, and the label is simply
 * small and quiet there.
 */
.faq-eyebrow {
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--store-muted);
}

[dir='rtl'] .faq-eyebrow {
  letter-spacing: normal;
  text-transform: none;
}

.faq-item {
  border: 1px solid var(--store-border);
  border-radius: 1rem;
  background-color: var(--store-background);
  transition: border-color 150ms ease, background-color 150ms ease;
}

.faq-item:hover {
  background-color: var(--store-surface);
}

/*
 * The open card is the one being read, so it separates from the closed ones —
 * by a step of background rather than a coloured edge, which at this size reads
 * as an error state.
 */
.faq-item[open] {
  background-color: var(--store-surface);
}

.faq-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  /* The whole row is the control, and it clears the 44px reachable floor. */
  min-block-size: 3.5rem;
  padding: 0.75rem 1.25rem;
  cursor: pointer;
  font-weight: 500;
  text-align: start;

  /* Removes the disclosure triangle in Chrome and Safari... */
  list-style: none;
}

.faq-summary::-webkit-details-marker {
  /* ...and in the older WebKit that ignores the line above. */
  display: none;
}

.faq-summary:focus-visible {
  outline: 2px solid var(--store-accent);
  outline-offset: -2px;
  border-radius: 1rem;
}

.faq-question {
  min-inline-size: 0;
}

/* ---- the marker
 *
 * Two strokes rather than a `+` glyph: a glyph's weight and size move with
 * whichever font the merchant has chosen, and this one has to stay optically
 * centred in a circle at every size.
 */
.faq-marker {
  position: relative;
  flex: none;
  inline-size: 1.75rem;
  block-size: 1.75rem;
  border: 1px solid var(--store-border);
  border-radius: 9999px;
  transition: border-color 150ms ease, background-color 150ms ease;
}

.faq-item[open] .faq-marker {
  border-color: var(--store-text);
}

.faq-marker-bar {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  inline-size: 0.625rem;
  block-size: 1.5px;
  margin-block-start: -0.75px;
  margin-inline-start: -0.3125rem;
  background-color: var(--store-text);
  border-radius: 9999px;
}

/*
 * The upright stroke is what makes it a plus. Turned flat it lies over the
 * other one and the plus becomes a minus — one rotation, rather than two icons
 * swapped, so the two states read as one control changing.
 */
.faq-marker-bar-upright {
  rotate: 90deg;
  transition: rotate 200ms cubic-bezier(0.2, 0, 0, 1);
}

.faq-item[open] .faq-marker-bar-upright {
  rotate: 0deg;
}

/* ---- the answer */
.faq-answer {
  padding-inline: 1.25rem;
  padding-block-end: 1.25rem;
}

.faq-answer-inner {
  font-size: 0.9375rem;
  line-height: 1.7;
  color: var(--store-muted);
}

.faq-answer-inner p + p {
  margin-block-start: 0.75rem;
}

/*
 * Opening, animated — where the browser can.
 *
 * `<details>` has always snapped open because its content has no height to
 * animate from. `interpolate-size` plus `::details-content` is the first way to
 * do this in CSS alone; where it is missing the whole block is skipped and the
 * panel snaps exactly as it does today. No script either way.
 */
@supports (interpolate-size: allow-keywords) {
  :root {
    interpolate-size: allow-keywords;
  }

  .faq-item::details-content {
    block-size: 0;
    overflow: hidden;
    transition:
      block-size 220ms cubic-bezier(0.2, 0, 0, 1),
      content-visibility 220ms allow-discrete;
  }

  .faq-item[open]::details-content {
    block-size: auto;
  }
}

/* ---- the way out of the list
 *
 * Somebody who has read every question and not found theirs is the visitor most
 * likely to leave, and the one most worth answering.
 */
.faq-more {
  margin-block-start: 2rem;
  padding: 1.5rem 1.25rem;
  border: 1px dashed var(--store-border);
  border-radius: 1rem;
  text-align: center;
}

.faq-more-title {
  font-weight: 600;
}

.faq-more-note {
  margin-block-start: 0.25rem;
  font-size: 0.875rem;
  color: var(--store-muted);
}

/*
 * Somebody who has asked not to see motion still gets every state change, just
 * without the movement between them.
 */
@media (prefers-reduced-motion: reduce) {
  .faq-item,
  .faq-marker,
  .faq-marker-bar-upright,
  .faq-item::details-content {
    transition: none;
  }
}

/* --------------------------------------------------------------- footer scale
 *
 * Each footer block carries its own size, set by the merchant, with separate
 * values for phones and desktops.
 *
 * The two values arrive as inline custom properties (`--fb-m` and `--fb-d`) —
 * an inline style cannot hold a media query, so the query lives here and simply
 * chooses which of the two to use. That keeps one static rule in the sheet
 * instead of a generated stylesheet per shop.
 *
 * Everything inside a block is sized in `em`, so ONE font-size on the block
 * scales its headings, its body text, its links and its images together. That
 * is what makes "make the footer bigger" mean what a merchant expects, rather
 * than moving the words and leaving the logo behind.
 */
.footer-block {
  /*
   * The scale in force at this width, as one variable.
   *
   * Exposing the winner as `--fb-scale` lets anything sized in pixels — the
   * social artwork, which has its own height — multiply by it and stay in step
   * with the text.
   */
  --fb-scale: var(--fb-m, 1);
  /* 0.875rem is the `text-sm` step — the footer's natural body size. */
  font-size: calc(0.875rem * var(--fb-scale));
}

@media (width >= 40rem) {
  .footer-block {
    --fb-scale: var(--fb-d, 1);
  }
}

/*
 * Inner type, relative to the block.
 *
 * Scoped with `:where()` so these carry zero specificity — any utility class on
 * the element still wins, and only the elements that would otherwise be pinned
 * to a rem size get converted.
 */
.footer-block :where(h2) {
  font-size: 1em;
}

.footer-block :where(p, li, a, span:not([class*='size-'])) {
  font-size: 1em;
}

/* The brand card's shop name, deliberately larger than body text. */
.footer-block :where(.footer-brand-name) {
  font-size: 1.3em;
}

/*
 * Images scale with the block.
 *
 * `em` rather than a fixed height, so the logo grows and shrinks with the words
 * beside it — a footer where the text doubled and the logo did not would look
 * broken rather than bigger.
 */
.footer-block :where(.footer-logo) {
  height: 2.3em;
  width: auto;
}

.footer-block :where(.footer-social-image) {
  /*
   * Set per link in pixels, then multiplied by the block's scale.
   *
   * Pixels rather than `em` because the merchant is sizing a specific picture
   * they uploaded, not a piece of text — but the scale still applies, so
   * enlarging the whole footer enlarges these with it.
   */
  height: calc(var(--social-h, 44px) * var(--fb-scale, 1));
  width: auto;
}

/*
 * A trust badge: sized by the merchant, and never wider than its column.
 *
 * The height is the number they chose, multiplied by the block's scale — the
 * same arrangement as a social icon, so enlarging the footer enlarges the
 * certification marks with it rather than leaving them behind.
 *
 * `object-fit` is the half that fixes the actual complaint, and it is worth
 * being precise about what that complaint was. The page never scrolled
 * sideways — the global `img { max-width: 100% }` reset already prevented that.
 * What happened instead is worse to look at: a wide certification strip had its
 * height pinned by the utility class and its width clamped by that reset, and
 * with the default `object-fit: fill` it was STRETCHED to whatever box was
 * left. Measured on a 390px screen, a 1200x120 mark was drawn at 7.46:1 instead
 * of 10:1 — a quarter of its width squeezed out of it.
 *
 * `contain` draws the picture in its own proportions inside the space it has.
 * `max-width` is kept here so the rule does not depend on the reset above it
 * still being there.
 */
.footer-block :where(.footer-badge-image) {
  height: calc(var(--badge-h, 48px) * var(--fb-scale, 1));
  width: auto;
  max-width: 100%;
  object-fit: contain;
}

/*
 * The tinted variant is a painted box, not an image.
 *
 * A masked element has no intrinsic size to derive a width from — `width: auto`
 * on a <span> is zero — so the upload's own proportions are passed in as a
 * ratio and the width is computed from the height. Same height as the untinted
 * case, so switching a link between the two does not move the row.
 */
.footer-block :where(.footer-social-tinted) {
  height: calc(var(--social-h, 44px) * var(--fb-scale, 1));
  width: calc(var(--social-h, 44px) * var(--fb-scale, 1) * var(--social-ratio, 1));
  background-color: currentColor;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-size: contain;
  mask-size: contain;
}

/*
 * ...but a touch target never shrinks below 44px.
 *
 * Scaling is a presentation choice; reachability is not negotiable, so the
 * floor wins over the merchant's percentage at the small end.
 */
.footer-block :where(a, button) {
  min-height: 44px;
}

.footer-block :where(li > a:not([class*='min-h'])) {
  display: inline-flex;
  align-items: center;
}

/* ------------------------------------------------------- the mobile nav gutter
 *
 * The bar is fixed, so it sits ON TOP of the page rather than in the flow.
 * Without this the last row of products, and the whole copyright line, are
 * permanently behind it — reachable only by scrolling past the end of the
 * document, which most browsers will not do.
 *
 * Only below `sm`, which is the only width the bar exists at. The safe-area
 * inset covers the home indicator on a modern iPhone; it resolves to 0
 * everywhere else, so it costs nothing there.
 */
@media (width < 40rem) {
  body.has-mobile-nav {
    padding-bottom: calc(3.5rem + env(safe-area-inset-bottom));
  }
}

/* ------------------------------------------------------------- the lightbox
 *
 * A photograph on its own, over everything. Its own dialog rather than the one
 * the panels use: opening it from inside a product panel must not destroy that
 * panel, and closing it must put the customer back exactly where they were.
 */
.cms-zoom {
  width: 100%;
  max-width: 100%;
  height: 100%;
  max-height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  align-items: center;
  justify-content: center;
}

.cms-zoom:not([open]) {
  display: none;
}

.cms-zoom[open] {
  display: flex;
}

.cms-zoom::backdrop {
  /* Darker than a panel's: the point is to look at the photograph, and a
     half-lit shop behind it competes for attention. */
  background: rgb(0 0 0 / 0.85);
}

.cms-zoom img {
  max-width: 100%;
  /* Room for the close control without the photograph sliding under it. */
  max-height: 88dvh;
  width: auto;
  height: auto;
  object-fit: contain;
}

.cms-zoom-close {
  position: fixed;
  inset-block-start: max(0.75rem, env(safe-area-inset-top));
  inset-inline-end: max(0.75rem, env(safe-area-inset-right));
  min-width: 2.75rem;
  min-height: 2.75rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  font-size: 1.5rem;
  line-height: 1;
  color: #fff;
  background-color: rgb(0 0 0 / 0.5);
}

.cms-zoom-close:hover {
  background-color: rgb(0 0 0 / 0.75);
}

/*
 * The frame only looks enlargeable once the script is running.
 *
 * `.js` is put on the document by app.js, so a customer without it gets a
 * button that does nothing and, correctly, does not look like it should.
 */
.js [data-gallery-zoom] {
  cursor: zoom-in;
}

/* ----------------------------------------------------------- the slider
 *
 * The strip is a scrolling element — that is what makes swiping work with no
 * script — but its scrollbar is chrome sitting across the bottom of a
 * photograph. The dots say where you are, and they say it better.
 *
 * Hidden, never disabled: the element still scrolls, still snaps, and still
 * responds to a trackpad or a shift-wheel. Only the bar is gone.
 */
[data-hero-track] {
  scrollbar-width: none;
  -ms-overflow-style: none;
}

[data-hero-track]::-webkit-scrollbar {
  display: none;
}

/* ------------------------------------------------------- switching results
 *
 * A category, a search, a page. Only part of the document is replaced, so the
 * browser shows nothing at all while it happens — on a slow connection a tap
 * looks like it did nothing, and gets tapped again.
 *
 * The region dims and stops taking clicks. Deliberately understated: this is
 * usually over in under a second, and a spinner that flashes for 200ms is more
 * distracting than a moment of stillness.
 */
[data-results][data-loading] {
  opacity: 0.55;
  /* The old products are still on screen and are about to be wrong; letting
     somebody tap one would open a panel for a product they did not choose. */
  pointer-events: none;
  cursor: progress;
  transition: opacity 120ms ease-out;
}

/*
 * ...but only once the wait is worth mentioning.
 *
 * The delay means a fast swap never dims at all, which is what stops the grid
 * flickering on every tap over a good connection.
 */
@media (prefers-reduced-motion: no-preference) {
  [data-results][data-loading] {
    transition-delay: 150ms;
  }
}

/* ---------------------------------------------------------- navigating
 *
 * A page fetched rather than loaded shows no browser progress bar, so somebody
 * on a slow connection gets no sign that their tap did anything. The cursor is
 * the smallest honest signal, and it costs nothing.
 */
[data-loading] {
  cursor: progress;
}

[data-loading] a,
[data-loading] button {
  /* Not `pointer-events: none`: the page is still usable, and a second tap
     simply supersedes the first. This only stops the cursor lying about it. */
  cursor: progress;
}

/* ---------------------------------------------------------------------- print
 *
 * The dashboard prints two things on purpose: an invoice and a shipping label.
 * Everything that frames them — navigation, buttons, the toolbar — is chrome
 * that wastes ink and confuses the person holding the paper.
 *
 * Written here rather than as utilities because none of it has a selector a
 * utility could carry: `@page` takes no class, and page-break behaviour is a
 * property of the document rather than of an element somebody styled.
 */
@media print {
  .no-print {
    display: none !important;
  }

  body {
    background: #fff;
    color: #000;
  }

  /*
   * A rule under a table heading is information, not decoration.
   *
   * Browsers drop backgrounds when printing to save ink, which on an invoice
   * takes the banding off the item table and the line under the total — the
   * two things telling somebody where the numbers stop. Asked for exactly, and
   * only inside a printed document.
   */
  .print-sheet {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  /* On paper a link is its text; a blue underline leads nowhere. */
  .print-sheet a {
    color: inherit;
    text-decoration: none;
  }
}

/* ------------------------------------------------------------------ the sheet
 *
 * What a printable document sits on while it is being reviewed.
 *
 * On screen it is a sheet of paper on a grey desk, so the operator checks the
 * thing that will come out rather than a page that resembles it. At print time
 * the layout strips the shadow and the margins, because the printer supplies
 * both.
 */
.print-sheet {
  width: 100%;
  border-radius: 0.5rem;
}

/*
 * Widows and orphans: typographic rather than visual, so no utility exists.
 *
 * Two lines minimum either side of a break. A heading alone at the foot of a
 * sheet, or one line of an address alone at the top of the next, is how a
 * printed document loses its reader.
 */
.print-sheet p,
.print-sheet td {
  orphans: 2;
  widows: 2;
}

/*
 * A long order's item table repeats its heading on every sheet.
 *
 * Without this, page two of an invoice is columns of numbers with nothing
 * saying which is the quantity and which is the price.
 */
.print-sheet thead {
  display: table-header-group;
}

.print-sheet tfoot {
  display: table-footer-group;
}

/* --------------------------------------------------------------- the dialog
 *
 * The basket, order tracking and a product's details open here rather than on a
 * page of their own — a customer half way down a grid of forty products should
 * not lose their place to look in the basket.
 *
 * Written by hand rather than as utilities, for two reasons: a `<dialog>` and
 * its `::backdrop` are pseudo-element territory, and this markup is built by
 * the script — the stylesheet builder scans templates, so a class that only
 * ever exists in JavaScript would never reach the generated half.
 *
 * ## Two shapes
 *
 * On a desktop it is a centred panel. On a phone it rises from the bottom edge
 * as a sheet, because the top of a tall phone is out of reach of the thumb
 * holding it — a centred box there puts the close button exactly where the hand
 * is not.
 */

/*
 * The dialog itself is the full viewport and does the positioning.
 *
 * A `<dialog>` sizes and centres itself by default, which fights any attempt to
 * pin it to an edge. Stripping that back to a full-bleed flex container makes
 * one element responsible for where the panel sits, so the phone and desktop
 * cases are one property apart rather than two independent layouts.
 */
/*
 * A CLOSED dialog is not laid out at all.
 *
 * The browser's own stylesheet says `dialog:not([open]) { display: none }`, and
 * the `display: flex` below overrode it — so closing a panel left a full-viewport
 * flex container with its white frame still in the page. An empty white box
 * nobody could get rid of, sitting over the shop.
 *
 * Declared first and separately, so it cannot be overridden by the block that
 * follows however that block grows.
 */
.cms-dialog:not([open]) {
  display: none;
}

.cms-dialog[open] {
  display: flex;
}

.cms-dialog {
  width: 100%;
  max-width: 100%;
  height: 100%;
  max-height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  /* Below `sm` the panel sits on the bottom edge; the media query lifts it.
     `display` is set by the `[open]` rules above, never here. */
  align-items: flex-end;
  justify-content: center;
  /*
   * The dialog scrolls, not the frame: an on-screen keyboard shrinks the
   * viewport, and a frame that owns the scrolling puts its own bottom out of
   * reach when that happens.
   *
   * BOTH axes are named, and that is the point. Setting only `overflow-y` does
   * not leave the other axis alone: when one axis scrolls and the other is
   * `visible`, the visible one computes to `auto`. So a rule that mentions
   * only the vertical quietly makes the panel horizontally scrollable too, and
   * anything exceeding the width by a fraction of a pixel — a rounded
   * percentage, a shadow, a focus ring — becomes a sideways drag on a phone.
   *
   * It never showed in an emulator because sub-pixel rounding depends on the
   * device's pixel ratio and its font metrics; it showed on a real handset.
   */
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.cms-dialog::backdrop {
  background: rgb(0 0 0 / 0.5);
  backdrop-filter: blur(2px);
}

.cms-dialog-frame {
  position: relative;
  width: 100%;
  max-width: 42rem;
  background-color: var(--store-background);
  color: var(--store-text);
  padding: 1.25rem;
  box-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.2), 0 8px 10px -6px rgb(0 0 0 / 0.2);

  /*
   * A sheet: square along the bottom edge it is sitting on, rounded above.
   * Rounding all four corners would leave two of them cut off by the screen.
   */
  border-start-start-radius: 1rem;
  border-start-end-radius: 1rem;

  /*
   * Never taller than most of the screen, so the page behind stays visible —
   * which is what tells somebody this is a layer over their place in the grid
   * rather than a page they navigated to.
   */
  max-height: 88dvh;

  /*
   * Named on both axes for the reason above. Nothing in this panel is meant to
   * be reached by scrolling sideways: the one thing that does scroll that way
   * — the gallery's thumbnail strip — carries its own `overflow-x`, so it
   * keeps its scroll and the sheet does not gain one.
   */
  overflow-x: hidden;
  overflow-y: auto;

  /*
   * And so a long unbroken token cannot push the width out in the first place.
   * Clipping alone would hide such a word rather than wrap it, which trades a
   * visible bug for a silent one.
   */
  overflow-wrap: break-word;

  /* Clear of the home indicator on a modern iPhone. */
  padding-block-end: calc(1.25rem + env(safe-area-inset-bottom));

  animation: cms-sheet-up 200ms cubic-bezier(0.2, 0, 0, 1);
}

@keyframes cms-sheet-up {
  from {
    translate: 0 100%;
  }
}

/*
 * From `sm` up, a centred panel.
 *
 * There is room for the whole thing on screen and a pointer to reach any part
 * of it, so the reason for anchoring it to an edge is gone.
 */
@media (width >= 40rem) {
  .cms-dialog {
    align-items: center;
    padding: 1.5rem;
  }

  .cms-dialog-frame {
    border-radius: 1rem;
    max-height: 85dvh;
    padding-block-end: 1.25rem;
    animation: cms-dialog-in 150ms cubic-bezier(0.2, 0, 0, 1);
  }
}

@keyframes cms-dialog-in {
  from {
    opacity: 0;
    scale: 0.98;
  }
}

/*
 * The close button sits in the trailing corner, which mirrors with direction:
 * `inset-inline-end` puts it top-left in Persian without a second rule.
 *
 * Sticky rather than absolute, so it stays reachable when the panel's contents
 * scroll — a long product description would otherwise carry it off the top.
 */
.cms-dialog-close {
  position: sticky;
  float: inline-end;
  inset-block-start: 0;
  /* Above the content it floats over. */
  z-index: 1;
  /* Never smaller than a reachable target, whatever the glyph measures. */
  min-width: 2.75rem;
  min-height: 2.75rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 0.5rem;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--store-muted);
  background-color: var(--store-background);
  transition: background-color 150ms, color 150ms;
}

.cms-dialog-close:hover {
  background-color: var(--store-surface);
  color: var(--store-text);
}

.cms-dialog-body {
  /* The float above is taken out of the flow, so this clears it. */
  clear: both;
}

.cms-dialog-loading {
  padding-block: 2rem;
  text-align: center;
  color: var(--store-muted);
}

/* ------------------------------------------------------- the search popup
 *
 * Anchored to the search field, which is why the field's parent is the
 * positioning context. The script adds `.cms-search-wrapper` to it rather than
 * the markup carrying it, so a form without the script has no stray relative
 * container changing how it lays out.
 */
.cms-search-wrapper {
  position: relative;
}

.cms-search-popup {
  position: absolute;
  inset-inline: 0;
  inset-block-start: calc(100% + 0.25rem);
  /*
   * Above the sticky header it hangs from, and above the phone bar — but below
   * a dialog, which the browser paints in its own top layer regardless.
   */
  z-index: 50;
  border-radius: 0.75rem;
  border: 1px solid var(--store-border);
  background-color: var(--store-background);
  box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
}

.cms-search-popup[hidden] {
  display: none;
}

/*
 * Form fields are never smaller than 16px on a phone.
 *
 * ## The problem this solves
 *
 * iOS Safari zooms the whole page in whenever a field it is focusing has a
 * font-size below 16px — and it does not zoom back out afterwards. Every input
 * in this shop is `text-sm`, which is 14px, so tapping the search box, the
 * tracking form or any checkout field left the customer on a page magnified
 * about 1.15x with the layout running off the side, and no obvious way back
 * except pinching.
 *
 * ## Why not `user-scalable=no`
 *
 * That is the answer this problem usually gets, and it is the wrong one. It
 * takes pinch-zoom away from everybody — the WCAG failure is 1.4.4, and the
 * people it hurts most are the ones who need to magnify text to read it at all.
 * Modern iOS ignores it anyway, so it would not even work.
 *
 * Giving iOS no reason to zoom is the fix. 16px is the threshold; at or above
 * it, nothing happens.
 *
 * ## The selector
 *
 * Every one of the three carries a `:not()`, and that is not decoration. A bare
 * element selector is one point of specificity and loses to the `.text-sm`
 * utility, so the rule silently does nothing — which is exactly what happened
 * on the first attempt: `input:not([type='hidden'])` won and reached 16px,
 * while the bare `select` beside it stayed at 14 and went on zooming. Measuring
 * the computed size at 390px is what found it. `:not()` takes its argument's
 * weight, so each of these is a class plus an element, and each wins.
 *
 * Only below `sm`. On a desktop there is no auto-zoom to avoid and the smaller
 * text is the design.
 */
@media (max-width: 639px) {
  input:not([type='hidden']),
  select:not([hidden]),
  textarea:not([hidden]) {
    font-size: 16px;
  }
}

/*
 * Long unbroken text wraps instead of widening what holds it.
 *
 * A URL, an order code, a bank reference — anything without a space in it — is
 * treated as one word, and a word that does not fit makes its container as wide
 * as the word. Inside a popup on a phone that is the whole bug: a tracking link
 * in a returns policy stretched the panel to 559px on a 320px screen and the
 * popup scrolled sideways. Measured, not guessed: the offending element was the
 * `<p>` itself, 539px wide inside a 320px panel.
 *
 * `anywhere`, and the difference from `break-word` is the whole fix.
 *
 * `break-word` was the first attempt and changed nothing, because the paragraph
 * was never given a narrow width to wrap into: it sits in a grid, grid items
 * default to `min-width: auto`, and that floor is the item's MIN-CONTENT size —
 * the length of the longest word. The runaway URL therefore set the track width
 * and the panel grew to match.
 *
 * The two values differ in exactly that place: soft wrap opportunities are
 * ignored when computing min-content under `break-word`, and counted under
 * `anywhere`. So `anywhere` lowers the floor and the grid can finally shrink.
 * Both only ever break a word that would otherwise overflow its line, so
 * ordinary prose still wraps at spaces either way.
 *
 * Set on `body` because it inherits, and because the same runaway token can
 * arrive anywhere a person types: a product description, a ticket message, an
 * order note, a footer policy. Fixing the containers one at a time would be
 * fixing this again every time a new one is added.
 *
 * It does not fight `white-space: nowrap` — a price or a table cell that must
 * stay on one line still does.
 */
body {
  overflow-wrap: anywhere;
}


/* ---------------------------------------------------------------- utilities
 *
 * Generated by bin/build-css.php from the classes app/Views actually uses.
 * Do not edit by hand — re-run the builder instead.
 *
 * 544 rules, built 2026-09-09.
 */
.-end-0\.5{inset-inline-end:-0.125rem}
.-end-2{inset-inline-end:-0.5rem}
.-mb-px{margin-bottom:-1px}
.-mx-1{margin-inline:-0.25rem}
.-mx-4{margin-inline:-1rem}
.-top-0\.5{top:-0.125rem}
.-top-1\.5{top:-0.375rem}
.-translate-x-1\/2{translate:-50% 0}
.-translate-y-1\/2{translate:0 -50%}
.absolute{position:absolute}
.accent-\[var\(--brand-primary\)\]{accent-color:var(--brand-primary)}
.accent-\[var\(--store-primary\)\]{accent-color:var(--store-primary)}
.align-top{vertical-align:top}
.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}
.aspect-\[16\/7\]{aspect-ratio:16 / 7}
.aspect-\[16\/9\]{aspect-ratio:16 / 9}
.aspect-\[3\/4\]{aspect-ratio:3 / 4}
.aspect-\[4\/3\]{aspect-ratio:4 / 3}
.aspect-square{aspect-ratio:1 / 1}
.backdrop-blur{backdrop-filter:blur(8px)}
.backdrop-blur-sm{backdrop-filter:blur(4px)}
.bg-\[var\(--brand-ink\)\]{background-color:var(--brand-ink)}
.bg-\[var\(--brand-primary\)\]{background-color:var(--brand-primary)}
.bg-\[var\(--brand-primary\)\]\/5{background-color:color-mix(in oklab,var(--brand-primary) 5%,transparent)}
.bg-\[var\(--store-accent\)\]{background-color:var(--store-accent)}
.bg-\[var\(--store-background\)\]{background-color:var(--store-background)}
.bg-\[var\(--store-background\)\]\/95{background-color:color-mix(in oklab,var(--store-background) 95%,transparent)}
.bg-\[var\(--store-border\)\]{background-color:var(--store-border)}
.bg-\[var\(--store-primary\)\]{background-color:var(--store-primary)}
.bg-\[var\(--store-surface\)\]{background-color:var(--store-surface)}
.bg-amber-100{background-color:#fef3c7}
.bg-amber-50{background-color:#fffbeb}
.bg-amber-500{background-color:#f59e0b}
.bg-black\/40{background-color:color-mix(in oklab,#000000 40%,transparent)}
.bg-black\/45{background-color:color-mix(in oklab,#000000 45%,transparent)}
.bg-black\/70{background-color:color-mix(in oklab,#000000 70%,transparent)}
.bg-black\/80{background-color:color-mix(in oklab,#000000 80%,transparent)}
.bg-blue-100{background-color:#dbeafe}
.bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--tw-gradient-stops))}
.bg-gray-100{background-color:#f3f4f6}
.bg-gray-200{background-color:#e5e7eb}
.bg-gray-300{background-color:#d1d5db}
.bg-gray-50{background-color:#f9fafb}
.bg-green-100{background-color:#dcfce7}
.bg-green-50{background-color:#f0fdf4}
.bg-green-600{background-color:#16a34a}
.bg-red-100{background-color:#fee2e2}
.bg-red-50{background-color:#fef2f2}
.bg-red-600{background-color:#dc2626}
.bg-transparent{background-color:transparent}
.bg-white{background-color:#ffffff}
.bg-white\/45{background-color:color-mix(in oklab,#ffffff 45%,transparent)}
.block{display:block}
.border{border-style:var(--tw-border-style,solid);border-width:1px}
.border-0{border-width:0}
.border-\[var\(--brand-primary\)\]{border-color:var(--brand-primary)}
.border-\[var\(--footer-border\)\]{border-color:var(--footer-border)}
.border-\[var\(--footer-line\)\]{border-color:var(--footer-line)}
.border-\[var\(--store-border\)\]{border-color:var(--store-border)}
.border-\[var\(--store-primary\)\]{border-color:var(--store-primary)}
.border-amber-200{border-color:#fde68a}
.border-b{border-style:var(--tw-border-style,solid);border-bottom-width:1px}
.border-b-2{border-bottom-width:2px}
.border-black{border-color:#000000}
.border-black\/10{border-color:color-mix(in oklab,#000000 10%,transparent)}
.border-collapse{border-collapse:collapse}
.border-dashed{border-style:dashed}
.border-gray-200{border-color:#e5e7eb}
.border-gray-300{border-color:#d1d5db}
.border-green-200{border-color:#bbf7d0}
.border-red-200{border-color:#fecaca}
.border-red-300{border-color:#fca5a5}
.border-s{border-style:var(--tw-border-style,solid);border-inline-start-width:1px}
.border-s-2{border-inline-start-width:2px}
.border-separate{border-collapse:separate}
.border-spacing-0{border-spacing:0}
.border-t{border-style:var(--tw-border-style,solid);border-top-width:1px}
.border-transparent{border-color:transparent}
.border-white\/15{border-color:color-mix(in oklab,#ffffff 15%,transparent)}
.border-white\/20{border-color:color-mix(in oklab,#ffffff 20%,transparent)}
.bottom-0{bottom:0rem}
.bottom-2{bottom:0.5rem}
.bottom-3{bottom:0.75rem}
.break-all{word-break:break-all}
.break-inside-avoid{break-inside:avoid}
.break-words{overflow-wrap:break-word}
.content-start{align-content:start}
.contents{display:contents}
.cursor-not-allowed{cursor:not-allowed}
.cursor-pointer{cursor:pointer}
.divide-\[var\(--store-border\)\] > :not([hidden]) ~ :not([hidden]){border-color:var(--store-border)}
.divide-gray-200 > :not([hidden]) ~ :not([hidden]){border-color:#e5e7eb}
.divide-y > :not([hidden]) ~ :not([hidden]){border-top-width:1px;border-style:var(--tw-border-style,solid)}
.duration-500{transition-duration:500ms}
.end-2{inset-inline-end:0.5rem}
.end-2\.5{inset-inline-end:0.625rem}
.fixed{position:fixed}
.flex{display:flex}
.flex-1{flex:1 1 0%}
.flex-col{flex-direction:column}
.flex-row{flex-direction:row}
.flex-wrap{flex-wrap:wrap}
.font-bold{font-weight:700}
.font-extrabold{font-weight:800}
.font-medium{font-weight:500}
.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.font-normal{font-weight:400}
.font-semibold{font-weight:600}
.from-black\/0{--tw-gradient-from:color-mix(in oklab,#000000 0%,transparent);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to,transparent)}
.gap-0\.5{gap:0.125rem}
.gap-1{gap:0.25rem}
.gap-1\.5{gap:0.375rem}
.gap-10{gap:2.5rem}
.gap-2{gap:0.5rem}
.gap-2\.5{gap:0.625rem}
.gap-3{gap:0.75rem}
.gap-4{gap:1rem}
.gap-5{gap:1.25rem}
.gap-6{gap:1.5rem}
.gap-8{gap:2rem}
.gap-x-2{column-gap:0.5rem}
.gap-x-3{column-gap:0.75rem}
.gap-y-1{row-gap:0.25rem}
.gap-y-2{row-gap:0.5rem}
.grid{display:grid}
.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}
.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}
.grow{flex-grow:1}
.grow-0{flex-grow:0}
.h-0\.5{height:0.125rem}
.h-12{height:3rem}
.h-2{height:0.5rem}
.h-2\.5{height:0.625rem}
.h-5{height:1.25rem}
.h-8{height:2rem}
.h-full{height:100%}
.h-px{height:1px}
.inline-block{display:inline-block}
.inline-flex{display:inline-flex}
.inset-0{inset:0rem}
.inset-x-0{inset-inline:0rem}
.items-baseline{align-items:baseline}
.items-center{align-items:center}
.items-end{align-items:flex-end}
.items-start{align-items:flex-start}
.items-stretch{align-items:stretch}
.justify-between{justify-content:space-between}
.justify-center{justify-content:center}
.justify-end{justify-content:flex-end}
.justify-self-start{justify-self:start}
.leading-4{line-height:1rem}
.leading-none{line-height:1}
.leading-relaxed{line-height:1.625}
.leading-snug{line-height:1.375}
.leading-tight{line-height:1.25}
.left-1\/2{left:50%}
.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}
.line-through{text-decoration-line:line-through}
.list-none{list-style-type:none}
.max-h-40{max-height:10rem}
.max-h-56{max-height:14rem}
.max-h-64{max-height:16rem}
.max-h-80{max-height:20rem}
.max-w-2xl{max-width:42rem}
.max-w-3xl{max-width:48rem}
.max-w-40{max-width:10rem}
.max-w-48{max-width:12rem}
.max-w-4xl{max-width:56rem}
.max-w-6xl{max-width:72rem}
.max-w-full{max-width:100%}
.max-w-md{max-width:28rem}
.max-w-prose{max-width:65ch}
.max-w-sm{max-width:24rem}
.max-w-xs{max-width:20rem}
.mb-0{margin-bottom:0rem}
.mb-1{margin-bottom:0.25rem}
.mb-2{margin-bottom:0.5rem}
.mb-3{margin-bottom:0.75rem}
.mb-4{margin-bottom:1rem}
.mb-5{margin-bottom:1.25rem}
.mb-6{margin-bottom:1.5rem}
.me-auto{margin-inline-end:auto}
.min-h-11{min-height:2.75rem}
.min-h-14{min-height:3.5rem}
.min-h-20{min-height:5rem}
.min-h-24{min-height:6rem}
.min-h-32{min-height:8rem}
.min-h-9{min-height:2.25rem}
.min-h-\[192px\]{min-height:192px}
.min-h-dvh{min-height:100dvh}
.min-w-0{min-width:0}
.min-w-11{min-width:2.75rem}
.min-w-32{min-width:8rem}
.min-w-36{min-width:9rem}
.min-w-4{min-width:1rem}
.min-w-40{min-width:10rem}
.min-w-44{min-width:11rem}
.min-w-48{min-width:12rem}
.min-w-56{min-width:14rem}
.min-w-8{min-width:2rem}
.min-w-max{min-width:max-content}
.ms-1{margin-inline-start:0.25rem}
.ms-2{margin-inline-start:0.5rem}
.ms-auto{margin-inline-start:auto}
.mt-0\.5{margin-top:0.125rem}
.mt-1{margin-top:0.25rem}
.mt-10{margin-top:2.5rem}
.mt-16{margin-top:4rem}
.mt-2{margin-top:0.5rem}
.mt-3{margin-top:0.75rem}
.mt-4{margin-top:1rem}
.mt-5{margin-top:1.25rem}
.mt-6{margin-top:1.5rem}
.mt-8{margin-top:2rem}
.mt-auto{margin-top:auto}
.mx-1{margin-inline:0.25rem}
.mx-auto{margin-inline:auto}
.object-contain{object-fit:contain}
.object-cover{object-fit:cover}
.opacity-0{opacity:0}
.opacity-50{opacity:0.5}
.opacity-60{opacity:0.6}
.opacity-70{opacity:0.7}
.opacity-75{opacity:0.75}
.opacity-80{opacity:0.8}
.outline-none{outline:2px solid transparent;outline-offset:2px}
.outline-offset-2{outline-offset:2px}
.overflow-auto{overflow:auto}
.overflow-hidden{overflow:hidden}
.overflow-x-auto{overflow-x:auto}
.overflow-y-auto{overflow-y:auto}
.overscroll-x-contain{overscroll-behavior-x:contain}
.p-0{padding:0rem}
.p-0\.5{padding:0.125rem}
.p-1{padding:0.25rem}
.p-2{padding:0.5rem}
.p-2\.5{padding:0.625rem}
.p-3{padding:0.75rem}
.p-4{padding:1rem}
.p-6{padding:1.5rem}
.p-8{padding:2rem}
.pb-0{padding-bottom:0rem}
.pb-1{padding-bottom:0.25rem}
.pb-2{padding-bottom:0.5rem}
.pb-3{padding-bottom:0.75rem}
.pb-5{padding-bottom:1.25rem}
.pb-8{padding-bottom:2rem}
.pb-\[env\(safe-area-inset-bottom\)\]{padding-bottom:env(safe-area-inset-bottom)}
.pb-px{padding-bottom:1px}
.pe-1{padding-inline-end:0.25rem}
.place-items-center{place-items:center}
.pointer-events-none{pointer-events:none}
.ps-2{padding-inline-start:0.5rem}
.ps-3{padding-inline-start:0.75rem}
.pt-1{padding-top:0.25rem}
.pt-2{padding-top:0.5rem}
.pt-3{padding-top:0.75rem}
.pt-4{padding-top:1rem}
.pt-5{padding-top:1.25rem}
.px-1{padding-inline:0.25rem}
.px-1\.5{padding-inline:0.375rem}
.px-2{padding-inline:0.5rem}
.px-2\.5{padding-inline:0.625rem}
.px-3{padding-inline:0.75rem}
.px-4{padding-inline:1rem}
.px-6{padding-inline:1.5rem}
.py-0\.5{padding-block:0.125rem}
.py-1{padding-block:0.25rem}
.py-1\.5{padding-block:0.375rem}
.py-10{padding-block:2.5rem}
.py-16{padding-block:4rem}
.py-2{padding-block:0.5rem}
.py-3{padding-block:0.75rem}
.py-3\.5{padding-block:0.875rem}
.py-4{padding-block:1rem}
.py-6{padding-block:1.5rem}
.py-8{padding-block:2rem}
.relative{position:relative}
.rounded{border-radius:0.25rem}
.rounded-2xl{border-radius:1rem}
.rounded-full{border-radius:3.40282e38px}
.rounded-lg{border-radius:0.5rem}
.rounded-t-lg{border-top-left-radius:0.5rem;border-top-right-radius:0.5rem}
.rounded-xl{border-radius:0.75rem}
.self-stretch{align-self:stretch}
.shadow-sm{box-shadow:0 1px 2px 0 rgb(0 0 0 / 0.05)}
.shadow-xl{box-shadow:0 20px 25px -5px rgb(0 0 0 / 0.1),0 8px 10px -6px rgb(0 0 0 / 0.1)}
.shrink-0{flex-shrink:0}
.size-10{width:2.5rem;height:2.5rem}
.size-12{width:3rem;height:3rem}
.size-14{width:3.5rem;height:3.5rem}
.size-16{width:4rem;height:4rem}
.size-2{width:0.5rem;height:0.5rem}
.size-20{width:5rem;height:5rem}
.size-4{width:1rem;height:1rem}
.size-5{width:1.25rem;height:1.25rem}
.size-6{width:1.5rem;height:1.5rem}
.size-7{width:1.75rem;height:1.75rem}
.size-8{width:2rem;height:2rem}
.size-9{width:2.25rem;height:2.25rem}
.size-full{width:100%;height:100%}
.snap-always{scroll-snap-stop:always}
.snap-center{scroll-snap-align:center}
.snap-mandatory{--tw-snap-strictness:mandatory}
.snap-x{scroll-snap-type:x var(--tw-snap-strictness, proximity)}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border-width:0}
.start-0{inset-inline-start:0rem}
.start-2{inset-inline-start:0.5rem}
.start-2\.5{inset-inline-start:0.625rem}
.sticky{position:sticky}
.tabular-nums{font-variant-numeric:tabular-nums}
.text-2xl{font-size:1.5rem;line-height:calc(2 / 1.5)}
.text-3xl{font-size:1.875rem;line-height:calc(2.25 / 1.875)}
.text-\[0\.8em\]{font-size:0.8em}
.text-\[10px\]{font-size:10px}
.text-\[11px\]{font-size:11px}
.text-\[var\(--footer-muted\)\]{color:var(--footer-muted)}
.text-\[var\(--store-accent-contrast\)\]{color:var(--store-accent-contrast)}
.text-\[var\(--store-muted\)\]{color:var(--store-muted)}
.text-\[var\(--store-primary-contrast\)\]{color:var(--store-primary-contrast)}
.text-\[var\(--store-text\)\]{color:var(--store-text)}
.text-amber-600{color:#d97706}
.text-amber-700{color:#b45309}
.text-amber-800{color:#92400e}
.text-amber-900{color:#78350f}
.text-balance{text-wrap:balance}
.text-base{font-size:1rem;line-height:calc(1.5 / 1)}
.text-center{text-align:center}
.text-end{text-align:end}
.text-gray-400{color:#9ca3af}
.text-gray-500{color:#6b7280}
.text-gray-600{color:#4b5563}
.text-gray-700{color:#374151}
.text-gray-900{color:#111827}
.text-green-600{color:#16a34a}
.text-green-700{color:#15803d}
.text-green-800{color:#166534}
.text-green-900{color:#14532d}
.text-lg{font-size:1.125rem;line-height:calc(1.75 / 1.125)}
.text-red-500{color:#ef4444}
.text-red-600{color:#dc2626}
.text-red-700{color:#b91c1c}
.text-red-800{color:#991b1b}
.text-red-900{color:#7f1d1d}
.text-sm{font-size:0.875rem;line-height:calc(1.25 / 0.875)}
.text-start{text-align:start}
.text-white{color:#ffffff}
.text-white\/35{color:color-mix(in oklab,#ffffff 35%,transparent)}
.text-white\/40{color:color-mix(in oklab,#ffffff 40%,transparent)}
.text-white\/55{color:color-mix(in oklab,#ffffff 55%,transparent)}
.text-white\/70{color:color-mix(in oklab,#ffffff 70%,transparent)}
.text-white\/80{color:color-mix(in oklab,#ffffff 80%,transparent)}
.text-xl{font-size:1.25rem;line-height:calc(1.75 / 1.25)}
.text-xs{font-size:0.75rem;line-height:calc(1 / 0.75)}
.to-black\/5{--tw-gradient-to:color-mix(in oklab,#000000 5%,transparent)}
.top-0{top:0rem}
.top-1\/2{top:50%}
.top-2{top:0.5rem}
.top-2\.5{top:0.625rem}
.tracking-tight{letter-spacing:-0.025em}
.tracking-wide{letter-spacing:0.025em}
.tracking-wider{letter-spacing:0.05em}
.tracking-widest{letter-spacing:0.1em}
.transition-\[width\]{transition-property:width;transition-timing-function:cubic-bezier(0.4,0,0.2,1);transition-duration:150ms}
.transition-all{transition-property:all;transition-timing-function:cubic-bezier(0.4,0,0.2,1);transition-duration:150ms}
.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(0.4,0,0.2,1);transition-duration:150ms}
.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(0.4,0,0.2,1);transition-duration:150ms}
.transition-shadow{transition-property:box-shadow;transition-timing-function:cubic-bezier(0.4,0,0.2,1);transition-duration:150ms}
.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:cubic-bezier(0.4,0,0.2,1);transition-duration:150ms}
.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.underline{text-decoration-line:underline}
.underline-offset-2{text-underline-offset:2px}
.uppercase{text-transform:uppercase}
.w-10{width:2.5rem}
.w-12{width:3rem}
.w-2\.5{width:0.625rem}
.w-2\/5{width:40%}
.w-20{width:5rem}
.w-24{width:6rem}
.w-28{width:7rem}
.w-32{width:8rem}
.w-4{width:1rem}
.w-\[130px\]{width:130px}
.w-auto{width:auto}
.w-fit{width:fit-content}
.w-full{width:100%}
.w-max{width:max-content}
.w-px{width:1px}
.whitespace-nowrap{white-space:nowrap}
.whitespace-pre-line{white-space:pre-line}
.z-10{z-index:10}
.z-40{z-index:40}
.hidden{display:none}
.active\:bg-\[var\(--store-surface\)\]:active{background-color:var(--store-surface)}
.aria-\[current\]\:bg-\[var\(--store-surface\)\][aria-current]{background-color:var(--store-surface)}
.aria-\[current\]\:bg-white[aria-current]{background-color:#ffffff}
.aria-\[current\]\:border-\[var\(--store-primary\)\][aria-current]{border-color:var(--store-primary)}
.aria-\[current\]\:border-gray-900[aria-current]{border-color:#111827}
.aria-\[current\]\:font-medium[aria-current]{font-weight:500}
.aria-\[current\]\:outline-2[aria-current]{outline-width:2px;outline-style:solid}
.aria-\[current\]\:outline-\[var\(--store-primary\)\][aria-current]{outline-color:var(--store-primary)}
.aria-\[current\]\:w-6[aria-current]{width:1.5rem}
.aria-\[invalid\]\:border-red-500[aria-invalid]{border-color:#ef4444}
.aria-\[selected\]\:border-\[var\(--brand-primary\)\][aria-selected]{border-color:var(--brand-primary)}
.aria-\[selected\]\:font-medium[aria-selected]{font-weight:500}
.aria-\[selected\]\:text-gray-900[aria-selected]{color:#111827}
.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}
.disabled\:opacity-35:disabled{opacity:0.35}
.disabled\:opacity-40:disabled{opacity:0.4}
.disabled\:opacity-50:disabled{opacity:0.5}
.file\:bg-\[var\(--store-surface\)\]::file-selector-button{background-color:var(--store-surface)}
.file\:bg-gray-100::file-selector-button{background-color:#f3f4f6}
.file\:bg-gray-200::file-selector-button{background-color:#e5e7eb}
.file\:border-0::file-selector-button{border-width:0}
.file\:me-2::file-selector-button{margin-inline-end:0.5rem}
.file\:me-3::file-selector-button{margin-inline-end:0.75rem}
.file\:px-2::file-selector-button{padding-inline:0.5rem}
.file\:px-3::file-selector-button{padding-inline:0.75rem}
.file\:py-1::file-selector-button{padding-block:0.25rem}
.file\:py-1\.5::file-selector-button{padding-block:0.375rem}
.file\:rounded::file-selector-button{border-radius:0.25rem}
.file\:rounded-lg::file-selector-button{border-radius:0.5rem}
.file\:rounded-md::file-selector-button{border-radius:0.375rem}
.file\:text-sm::file-selector-button{font-size:0.875rem;line-height:calc(1.25 / 0.875)}
.file\:text-xs::file-selector-button{font-size:0.75rem;line-height:calc(1 / 0.75)}
.focus-visible\:-outline-offset-2:focus-visible{outline-offset:-2px}
.focus-visible\:bg-\[var\(--store-surface\)\]:focus-visible{background-color:var(--store-surface)}
.focus-visible\:border-gray-900:focus-visible{border-color:#111827}
.focus-visible\:outline-2:focus-visible{outline-width:2px;outline-style:solid}
.focus-visible\:outline-\[var\(--brand-accent\)\]:focus-visible{outline-color:var(--brand-accent)}
.focus-visible\:outline-\[var\(--brand-primary\)\]:focus-visible{outline-color:var(--brand-primary)}
.focus-visible\:outline-\[var\(--store-accent\)\]:focus-visible{outline-color:var(--store-accent)}
.focus-visible\:outline-gray-900:focus-visible{outline-color:#111827}
.focus-visible\:outline-offset-1:focus-visible{outline-offset:1px}
.focus-visible\:outline-offset-2:focus-visible{outline-offset:2px}
.focus-visible\:outline-red-600:focus-visible{outline-color:#dc2626}
.focus-visible\:outline-white:focus-visible{outline-color:#ffffff}
.focus\:absolute:focus{position:absolute}
.focus\:bg-\[var\(--store-primary\)\]:focus{background-color:var(--store-primary)}
.focus\:bg-gray-900:focus{background-color:#111827}
.focus\:not-sr-only:focus{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip-path:none;white-space:normal}
.focus\:px-3:focus{padding-inline:0.75rem}
.focus\:py-2:focus{padding-block:0.5rem}
.focus\:rounded:focus{border-radius:0.25rem}
.focus\:rounded-lg:focus{border-radius:0.5rem}
.focus\:start-2:focus{inset-inline-start:0.5rem}
.focus\:start-4:focus{inset-inline-start:1rem}
.focus\:text-\[var\(--store-primary-contrast\)\]:focus{color:var(--store-primary-contrast)}
.focus\:text-sm:focus{font-size:0.875rem;line-height:calc(1.25 / 0.875)}
.focus\:text-white:focus{color:#ffffff}
.focus\:top-2:focus{top:0.5rem}
.focus\:top-4:focus{top:1rem}
.focus\:z-50:focus{z-index:50}
.has-\[\:checked\]\:bg-\[var\(--store-surface\)\]:has(:checked){background-color:var(--store-surface)}
.has-\[\:checked\]\:border-\[var\(--store-primary\)\]:has(:checked){border-color:var(--store-primary)}
.has-\[\:disabled\]\:cursor-not-allowed:has(:disabled){cursor:not-allowed}
.has-\[\:disabled\]\:opacity-50:has(:disabled){opacity:0.5}
.hover\:bg-\[var\(--footer-surface\)\]:hover{background-color:var(--footer-surface)}
.hover\:bg-\[var\(--store-background\)\]:hover{background-color:var(--store-background)}
.hover\:bg-\[var\(--store-surface\)\]:hover{background-color:var(--store-surface)}
.hover\:bg-amber-100:hover{background-color:#fef3c7}
.hover\:bg-black\/60:hover{background-color:color-mix(in oklab,#000000 60%,transparent)}
.hover\:bg-black\/65:hover{background-color:color-mix(in oklab,#000000 65%,transparent)}
.hover\:bg-gray-100:hover{background-color:#f3f4f6}
.hover\:bg-gray-50:hover{background-color:#f9fafb}
.hover\:bg-red-50:hover{background-color:#fef2f2}
.hover\:bg-white\/10:hover{background-color:color-mix(in oklab,#ffffff 10%,transparent)}
.hover\:no-underline:hover{text-decoration-line:none}
.hover\:opacity-80:hover{opacity:0.8}
.hover\:shadow-md:hover{box-shadow:0 4px 6px -1px rgb(0 0 0 / 0.1),0 2px 4px -2px rgb(0 0 0 / 0.1)}
.hover\:text-\[var\(--footer-text\)\]:hover{color:var(--footer-text)}
.hover\:text-\[var\(--store-text\)\]:hover{color:var(--store-text)}
.hover\:text-amber-900:hover{color:#78350f}
.hover\:text-gray-900:hover{color:#111827}
.hover\:text-red-600:hover{color:#dc2626}
.hover\:text-red-700:hover{color:#b91c1c}
.hover\:text-white:hover{color:#ffffff}
.hover\:underline:hover{text-decoration-line:underline}
@media (prefers-reduced-motion: no-preference){:where(.group):hover .motion-safe\:group-hover\:scale-\[1\.03\]{scale:1.03}}
@media print{.print\:p-0{padding:0rem}}
@media print{.print\:p-4{padding:1rem}}
:where([dir="rtl"]) .rtl\:-scale-x-100{scale:-1 1}
@supports (backdrop-filter: blur(1px)){.supports-backdrop\:bg-\[var\(--store-background\)\]\/80{background-color:color-mix(in oklab,var(--store-background) 80%,transparent)}}
@supports (backdrop-filter: blur(1px)){.supports-backdrop\:bg-\[var\(--store-background\)\]\/85{background-color:color-mix(in oklab,var(--store-background) 85%,transparent)}}
@media (width >= 40rem){.sm\:aspect-\[16\/7\]{aspect-ratio:16 / 7}}
@media (width >= 40rem){.sm\:block{display:block}}
@media (width >= 40rem){.sm\:col-span-2{grid-column:span 2 / span 2}}
@media (width >= 40rem){.sm\:col-span-4{grid-column:span 4 / span 4}}
@media (width >= 40rem){.sm\:flex{display:flex}}
@media (width >= 40rem){.sm\:flex-1{flex:1 1 0%}}
@media (width >= 40rem){.sm\:gap-4{gap:1rem}}
@media (width >= 40rem){.sm\:grid{display:grid}}
@media (width >= 40rem){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (width >= 40rem){.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (width >= 40rem){.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}
@media (width >= 40rem){.sm\:grid-cols-\[10rem_minmax\(0\,1fr\)\]{grid-template-columns:10rem minmax(0,1fr)}}
@media (width >= 40rem){.sm\:grid-cols-\[14rem_minmax\(0\,1fr\)\]{grid-template-columns:14rem minmax(0,1fr)}}
@media (width >= 40rem){.sm\:grid-cols-\[1fr_1fr_2fr_auto\]{grid-template-columns:1fr 1fr 2fr auto}}
@media (width >= 40rem){.sm\:grid-cols-\[1fr_1fr_7rem\]{grid-template-columns:1fr 1fr 7rem}}
@media (width >= 40rem){.sm\:grid-cols-\[1fr_1fr_8rem_auto\]{grid-template-columns:1fr 1fr 8rem auto}}
@media (width >= 40rem){.sm\:grid-cols-\[1fr_1fr_auto\]{grid-template-columns:1fr 1fr auto}}
@media (width >= 40rem){.sm\:grid-cols-\[1fr_2fr_auto\]{grid-template-columns:1fr 2fr auto}}
@media (width >= 40rem){.sm\:grid-cols-\[1fr_9rem\]{grid-template-columns:1fr 9rem}}
@media (width >= 40rem){.sm\:grid-cols-\[1fr_auto\]{grid-template-columns:1fr auto}}
@media (width >= 40rem){.sm\:grid-cols-\[2fr_1fr\]{grid-template-columns:2fr 1fr}}
@media (width >= 40rem){.sm\:grid-cols-\[minmax\(0\,1fr\)_7rem\]{grid-template-columns:minmax(0,1fr) 7rem}}
@media (width >= 40rem){.sm\:h-9{height:2.25rem}}
@media (width >= 40rem){.sm\:inline{display:inline}}
@media (width >= 40rem){.sm\:inline-flex{display:inline-flex}}
@media (width >= 40rem){.sm\:items-end{align-items:flex-end}}
@media (width >= 40rem){.sm\:justify-items-end{justify-items:end}}
@media (width >= 40rem){.sm\:ms-0{margin-inline-start:0rem}}
@media (width >= 40rem){.sm\:mx-0{margin-inline:0rem}}
@media (width >= 40rem){.sm\:order-none{order:0}}
@media (width >= 40rem){.sm\:p-4{padding:1rem}}
@media (width >= 40rem){.sm\:p-5{padding:1.25rem}}
@media (width >= 40rem){.sm\:p-8{padding:2rem}}
@media (width >= 40rem){.sm\:px-0{padding-inline:0rem}}
@media (width >= 40rem){.sm\:px-6{padding-inline:1.5rem}}
@media (width >= 40rem){.sm\:text-3xl{font-size:1.875rem;line-height:calc(2.25 / 1.875)}}
@media (width >= 40rem){.sm\:text-end{text-align:end}}
@media (width >= 40rem){.sm\:w-\[150px\]{width:150px}}
@media (width >= 40rem){.sm\:hidden{display:none}}
@media (width >= 48rem){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (width >= 64rem){.lg\:block{display:block}}
@media (width >= 64rem){.lg\:border-0{border-width:0}}
@media (width >= 64rem){.lg\:flex{display:flex}}
@media (width >= 64rem){.lg\:flex-col{flex-direction:column}}
@media (width >= 64rem){.lg\:flex-row{flex-direction:row}}
@media (width >= 64rem){.lg\:gap-1{gap:0.25rem}}
@media (width >= 64rem){.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (width >= 64rem){.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}
@media (width >= 64rem){.lg\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}}
@media (width >= 64rem){.lg\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}}
@media (width >= 64rem){.lg\:grid-cols-\[minmax\(0\,1fr\)_20rem\]{grid-template-columns:minmax(0,1fr) 20rem}}
@media (width >= 64rem){.lg\:grid-cols-\[minmax\(0\,2fr\)_minmax\(0\,1fr\)\]{grid-template-columns:minmax(0,2fr) minmax(0,1fr)}}
@media (width >= 64rem){.lg\:ms-0{margin-inline-start:0rem}}
@media (width >= 64rem){.lg\:mt-auto{margin-top:auto}}
@media (width >= 64rem){.lg\:ps-0{padding-inline-start:0rem}}
@media (width >= 64rem){.lg\:self-start{align-self:flex-start}}
@media (width >= 64rem){.lg\:sticky{position:sticky}}
@media (width >= 64rem){.lg\:top-4{top:1rem}}
@media (width >= 64rem){.lg\:w-60{width:15rem}}
@media (width >= 64rem){.lg\:w-full{width:100%}}
