/*
  Duka storefront.

  Every value here comes from the design canvas token panel (artboard 1j) and is FIXED. The only
  merchant input is --brand, set inline per shop by the layout, from which --on-brand and
  --brand-tint are derived server-side.

  Two rules that look like omissions and are not:
    * No shadows anywhere. Elevation is a 1px line on a white surface. Shadows blur on low-DPI
      panels and wash out in sunlight, which is the daylight-in-Kampala case, not an edge case.
    * Nothing below 12px, and product names never below 14px.
*/

:root {
    --ink: #1B1916;
    --text-2: #5C5750;
    --meta: #7A746B;
    --surface: #F7F5F1;
    --surface-2: #EFECE6;
    --surface-3: #F5F2ED;
    --border: #E6E1D9;
    --border-2: #DCD6CC;
    --muted: #C9C3B9;
    --white: #FFFFFF;

    --r-sm: 6px;
    --r-md: 10px;
    --r-lg: 12px;
    --r-xl: 14px;
    --r-pill: 999px;

    --gutter: 16px;
}

* { box-sizing: border-box; }

/*
   The hidden attribute has to beat a layout class. Any rule that sets display - .picker and .panel
   both do - outranks the user agent's [hidden] { display: none }, so markup that says hidden was
   rendered anyway. It showed up as the stock box and the empty combination panel both visible on a
   product with no options chosen, which is exactly the state they exist to be absent from.
*/
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    background: var(--surface);
    color: var(--ink);
    font-family: "Public Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    font-size: 14px;
    font-weight: 500;
    line-height: 1.5;
}

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

img { max-width: 100%; display: block; }

button { font: inherit; color: inherit; border: none; background: none; cursor: pointer; }

input, select, textarea { font: inherit; color: inherit; }

/* The phone frame. Above 420px the shop centres rather than stretching: this design is specified
   at 360px and a 1200px-wide product grid would be a different design, not a wider one. */
.shell {
    max-width: 420px;
    margin: 0 auto;
    background: var(--surface);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

/* ---------- type scale ---------- */

.t-price-xl { font-size: 26px; font-weight: 700; letter-spacing: -0.02em; }
.t-title    { font-size: 20px; font-weight: 700; letter-spacing: -0.01em; line-height: 1.25; }
.t-heading  { font-size: 16px; font-weight: 700; }
.t-price    { font-size: 15px; font-weight: 700; }
.t-body     { font-size: 14px; font-weight: 500; }
.t-chip     { font-size: 13px; font-weight: 600; }
.t-meta     { font-size: 12px; font-weight: 400; color: var(--meta); }

.t-label {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--meta);
}

/* ---------- header ---------- */

.header {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px var(--gutter) 10px;
    background: var(--white);
}

.header__logo {
    width: 36px;
    height: 36px;
    border-radius: 8px;
    background: var(--surface-2);
    flex: none;
    object-fit: contain;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    font-weight: 700;
    color: var(--meta);
}

.header__names { flex: 1; min-width: 0; }

.header__shop {
    font-size: 16px;
    font-weight: 700;
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.header__sub { font-size: 12px; color: var(--meta); line-height: 1.2; }

/* The 3px brand rule under the header. One of the five places brand is allowed. */
.brand-rule { height: 3px; background: var(--brand); }

.back {
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
}

.back__glyph {
    width: 10px;
    height: 10px;
    border-left: 2px solid var(--ink);
    border-bottom: 2px solid var(--ink);
    transform: rotate(45deg);
    margin-left: 4px;
}

/* ---------- cart button ---------- */

.cart-button {
    width: 44px;
    height: 44px;
    border-radius: var(--r-lg);
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    flex: none;
}

.cart-button__glyph {
    width: 20px;
    height: 16px;
    border: 2px solid var(--ink);
    border-top-width: 3px;
    border-radius: 3px 3px 6px 6px;
}

.cart-button__count {
    position: absolute;
    top: 6px;
    right: 6px;
    min-width: 18px;
    height: 18px;
    padding: 0 4px;
    border-radius: 9px;
    background: var(--brand);
    color: var(--on-brand);
    font-size: 11px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* ---------- page body ---------- */

.page {
    padding: 14px var(--gutter) 0;
    display: flex;
    flex-direction: column;
    gap: 18px;
    flex: 1;
}

.section { display: flex; flex-direction: column; gap: 12px; }

.section__head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
}

.section__link {
    font-size: 14px;
    font-weight: 600;
    color: var(--brand);
    min-height: 44px;
    display: flex;
    align-items: center;
}

/* ---------- search ---------- */

.search {
    height: 44px;
    border-radius: var(--r-lg);
    background: var(--white);
    border: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 14px;
    color: var(--meta);
    font-size: 14px;
    width: 100%;
}

.search__glyph {
    width: 14px;
    height: 14px;
    border: 2px solid var(--meta);
    border-radius: 50%;
    flex: none;
}

.search input {
    border: none;
    outline: none;
    background: none;
    flex: 1;
    min-width: 0;
    color: var(--ink);
}

/* ---------- category rail ---------- */

.rail {
    display: flex;
    gap: 10px;
    overflow-x: auto;
    margin: 0 calc(var(--gutter) * -1);
    padding: 0 var(--gutter);
    scrollbar-width: none;
}

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

.rail__item { flex: none; width: 96px; display: flex; flex-direction: column; gap: 6px; }

.rail__frame {
    aspect-ratio: 1;
    border-radius: var(--r-xl);
    background: var(--surface-2);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    padding: 8%;
}

.rail__frame img { width: 100%; height: 100%; object-fit: contain; }

.rail__label { font-size: 13px; font-weight: 600; text-align: center; }

/* ---------- product grid ---------- */

.grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px 12px;
}

.card { display: flex; flex-direction: column; gap: 8px; }

/*
  The 4:5 frame with contain and an 8% inset is what turns a merchant's mixed phone photos into a
  catalogue: portrait, landscape and square shots all read as one grid.
*/
.frame {
    aspect-ratio: 4 / 5;
    border-radius: var(--r-lg);
    background: var(--surface-2);
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 8%;
    position: relative;
}

.frame img { width: 100%; height: 100%; object-fit: contain; }

/* Stands in for a photo the merchant has not uploaded yet, in the canvas's own hatch. */
.frame__placeholder {
    width: 70%;
    height: 85%;
    border-radius: 3px;
    background: repeating-linear-gradient(135deg, var(--border-2) 0 5px, var(--border) 5px 10px);
}

.frame__tag {
    position: absolute;
    top: 8px;
    left: 8px;
    background: var(--brand);
    color: var(--on-brand);
    font-size: 11px;
    font-weight: 700;
    padding: 3px 7px;
    border-radius: var(--r-sm);
}

.card__meta { display: flex; flex-direction: column; gap: 2px; }
.card__name { font-size: 14px; font-weight: 500; line-height: 1.3; }

/* ---------- chips ---------- */

.chips {
    display: flex;
    gap: 8px;
    overflow-x: auto;
    padding: 12px var(--gutter);
    margin: 0 calc(var(--gutter) * -1);
    scrollbar-width: none;
}

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

.chip {
    flex: none;
    height: 36px;
    padding: 0 14px;
    border-radius: var(--r-pill);
    border: 1.5px solid var(--border);
    background: var(--white);
    color: var(--text-2);
    font-size: 13px;
    font-weight: 600;
    display: flex;
    align-items: center;
    /* 36px tall but a 44px hit area, per the touch rules. */
    position: relative;
}

.chip::after {
    content: "";
    position: absolute;
    inset: -4px 0;
}

.chip--on {
    border-color: var(--brand);
    background: var(--brand-tint);
    color: var(--ink);
}

/* ---------- product detail ---------- */

.hero {
    aspect-ratio: 4 / 5;
    background: var(--surface-2);
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 6%;
}

.hero img { width: 100%; height: 100%; object-fit: contain; }

.hero__back {
    position: absolute;
    top: 8px;
    left: 8px;
    width: 44px;
    height: 44px;
    border-radius: 22px;
    background: rgba(255, 255, 255, 0.92);
    display: flex;
    align-items: center;
    justify-content: center;
}

.thumbs { display: flex; gap: 8px; padding: 10px var(--gutter) 0; overflow-x: auto; scrollbar-width: none; }
.thumbs::-webkit-scrollbar { display: none; }

.thumb {
    width: 56px;
    height: 56px;
    border-radius: 8px;
    background: var(--surface-2);
    border: 2px solid transparent;
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    overflow: hidden;
}

.thumb--on { border-color: var(--brand); }
.thumb img { width: 100%; height: 100%; object-fit: contain; }

.options { display: flex; gap: 8px; flex-wrap: wrap; }

.option {
    flex: 1 0 auto;
    min-width: 56px;
    height: 44px;
    border-radius: var(--r-md);
    border: 1.5px solid var(--border);
    background: var(--white);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    font-weight: 600;
}

/* A colour, shown as a colour. The ring is a hairline rather than a shadow, so a white swatch
   still reads as a swatch on a white card. */
.swatch {
    width: 18px;
    height: 18px;
    border-radius: 9px;
    border: 1px solid rgba(27, 25, 22, 0.18);
    flex: none;
    display: inline-block;
}

.option { gap: 6px; }

.option--on,
.option:has(input:checked) { border-color: var(--brand); background: var(--brand-tint); }

.option:focus-within { outline: 2px solid var(--brand); outline-offset: 2px; }

.option--out {
    color: var(--muted);
    border-style: dashed;
    text-decoration: line-through;
}

.accordion { display: flex; flex-direction: column; border-top: 1px solid var(--border); }

.accordion summary {
    display: flex;
    justify-content: space-between;
    align-items: center;
    min-height: 48px;
    border-bottom: 1px solid var(--border);
    font-size: 14px;
    font-weight: 500;
    list-style: none;
    cursor: pointer;
}

.accordion summary::-webkit-details-marker { display: none; }
.accordion summary::after { content: "+"; color: var(--meta); font-size: 18px; }
.accordion details[open] summary::after { content: "\2212"; }
.accordion .accordion__body { padding: 0 0 12px; font-size: 14px; color: var(--text-2); }

/* ---------- sticky action bar ---------- */

.sticky {
    position: sticky;
    bottom: 0;
    padding: 12px var(--gutter) 14px;
    background: var(--white);
    /* A line, not a shadow. */
    border-top: 1px solid var(--border);
    display: flex;
    gap: 10px;
    /* auto, not a fixed gap: on a short page the bar sits at the bottom of the screen where a
       thumb expects it, and on a long one it still sticks while scrolling. */
    margin-top: auto;
}

.cta {
    flex: 1;
    min-height: 52px;
    border-radius: var(--r-xl);
    background: var(--brand);
    color: var(--on-brand);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    font-size: 16px;
    font-weight: 700;
    text-align: center;
    padding: 0 12px;
    width: 100%;
}

.cta--ghost {
    background: var(--white);
    color: var(--ink);
    border: 1.5px solid var(--border);
}

.cta[disabled] { background: var(--muted); color: var(--white); }

.cta__whatsapp {
    width: 20px;
    height: 20px;
    border-radius: 50%;
    border: 2.5px solid currentColor;
    position: relative;
    flex: none;
}

.cta__whatsapp::after {
    content: "";
    position: absolute;
    left: -4px;
    bottom: -3px;
    border: 5px solid transparent;
    border-top-color: currentColor;
    transform: rotate(30deg);
}

.icon-button {
    width: 52px;
    height: 52px;
    border-radius: var(--r-xl);
    border: 1.5px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
}

/* ---------- cards, rows, lists ---------- */

.panel {
    background: var(--white);
    border-radius: var(--r-xl);
    border: 1px solid var(--border);
    overflow: hidden;
}

.row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 14px;
    min-height: 52px;
    border-bottom: 1px solid var(--border);
    width: 100%;
    text-align: left;
}

.row:last-child { border-bottom: none; }
.row--on,
.row:has(input:checked) { background: var(--brand-tint); }

.radio {
    width: 22px;
    height: 22px;
    border-radius: 11px;
    border: 2px solid var(--border-2);
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
}

.row--on .radio,
.row:has(input:checked) .radio { border-color: var(--brand); }
.radio__dot { width: 10px; height: 10px; border-radius: 5px; background: transparent; }
.row--on .radio__dot,
.row:has(input:checked) .radio__dot { background: var(--brand); }

.row__label { flex: 1; font-size: 14px; font-weight: 500; }
.row__value { font-size: 14px; font-weight: 600; color: var(--text-2); }

/* ---------- cart lines ---------- */

.line { display: flex; gap: 12px; padding: 12px; border-bottom: 1px solid var(--border); }
.line:last-child { border-bottom: none; }

.line__frame {
    width: 72px;
    height: 90px;
    border-radius: 8px;
    background: var(--surface-2);
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    padding: 6%;
}

.line__frame img { width: 100%; height: 100%; object-fit: contain; }

.line__body {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    min-width: 0;
    gap: 8px;
}

.stepper {
    display: flex;
    align-items: center;
    border: 1.5px solid var(--border);
    border-radius: var(--r-md);
    height: 36px;
}

.stepper button {
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;
    color: var(--text-2);
}

.stepper__qty { min-width: 24px; text-align: center; font-size: 14px; font-weight: 600; }

/* ---------- editor photo gallery ---------- */

.gallery { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; }

.gallery__item { display: flex; flex-direction: column; gap: 4px; }

.gallery__badge {
    font-size: 11px;
    font-weight: 700;
    color: var(--on-brand);
    background: var(--brand);
    border-radius: var(--r-sm);
    padding: 3px 6px;
    text-align: center;
}

.gallery__action {
    font-size: 12px;
    font-weight: 600;
    min-height: 32px;
    border-radius: var(--r-sm);
    border: 1px solid var(--border);
    background: var(--white);
}

.gallery__action--remove { color: #B3261E; }

/* ---------- editor option rows ---------- */

.optrow {
    padding: 12px;
    border-bottom: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.optrow:last-child { border-bottom: none; }

.optrow__line { display: flex; gap: 8px; align-items: center; }

.optrow__line select,
.optrow__line input {
    min-height: 44px;
    border: 1.5px solid var(--border);
    border-radius: var(--r-md);
    padding: 8px 10px;
    background: var(--white);
    min-width: 0;
}

.optrow__line select { flex: 1.4; }
.optrow__line input { flex: 1; width: 100%; }

/* The colour row scrolls rather than wrapping into four ragged lines on a 360px screen. */
.swatches {
    display: flex;
    gap: 8px;
    overflow-x: auto;
    padding-bottom: 2px;
    scrollbar-width: none;
}

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

.swatchpick {
    flex: none;
    width: 32px;
    height: 32px;
    border-radius: 16px;
    border: 2px solid transparent;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
}

/* 32px drawn, 44px touchable — the swatches would otherwise be the smallest targets on the page. */
.swatchpick::after { content: ""; position: absolute; inset: -6px; }

.swatchpick--on,
.swatchpick:has(input:checked) { border-color: var(--ink); }

.swatchpick .swatch { width: 22px; height: 22px; border-radius: 11px; }

.swatchpick__none {
    width: 22px;
    height: 22px;
    border-radius: 11px;
    border: 1px solid var(--border-2);
    background:
        linear-gradient(to bottom right, transparent calc(50% - 1px),
        var(--muted) calc(50% - 1px), var(--muted) calc(50% + 1px), transparent calc(50% + 1px)),
        var(--white);
}

.field select {
    min-height: 48px;
    border-radius: var(--r-md);
    border: 1.5px solid var(--border);
    background: var(--white);
    padding: 12px 14px;
    width: 100%;
}

/* ---------- totals ---------- */

.totals { display: flex; flex-direction: column; gap: 8px; font-size: 14px; color: var(--text-2); }
.totals__row { display: flex; justify-content: space-between; gap: 12px; }

.totals__total {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding-top: 10px;
    border-top: 1px solid var(--border);
    color: var(--ink);
}

.totals__total b { font-size: 22px; font-weight: 700; letter-spacing: -0.02em; }

/* ---------- payment note ---------- */

.paynote {
    background: var(--white);
    border-radius: var(--r-xl);
    border: 1px solid var(--border);
    padding: 12px 14px;
    display: flex;
    gap: 12px;
    align-items: flex-start;
    font-size: 13px;
    line-height: 1.45;
    color: var(--text-2);
}

.paynote strong { color: var(--ink); }
.paynote__marks { display: flex; gap: 4px; flex: none; margin-top: 2px; }

.paymark {
    width: 22px;
    height: 22px;
    border-radius: var(--r-sm);
    font-size: 7px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
}

.paymark--mtn { background: #FFCC00; color: #1B1916; }
.paymark--airtel { background: #E4002B; color: #FFFFFF; font-size: 6px; }
.paymark--cash { background: var(--surface-2); color: var(--text-2); }

/* ---------- forms ---------- */

.field { display: flex; flex-direction: column; gap: 6px; }
.field label { font-size: 14px; font-weight: 600; }

.field input, .field textarea {
    min-height: 48px;
    border-radius: var(--r-md);
    border: 1.5px solid var(--border);
    background: var(--white);
    padding: 12px 14px;
    outline: none;
    width: 100%;
}

.field input:focus, .field textarea:focus { border-color: var(--brand); }
.field textarea { min-height: 88px; resize: vertical; }

.field__error { font-size: 12px; color: #B3261E; font-weight: 600; }

/* ---------- empty and loading ---------- */

.empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    text-align: center;
    padding: 48px 24px;
}

.empty__glyph {
    width: 64px;
    height: 64px;
    border-radius: var(--r-xl);
    background: var(--surface-2);
    display: flex;
    align-items: center;
    justify-content: center;
}

.skeleton {
    background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 50%, var(--surface-2) 75%);
    background-size: 200% 100%;
    animation: shimmer 1.4s linear infinite;
    border-radius: var(--r-lg);
}

@keyframes shimmer {
    from { background-position: 200% 0; }
    to { background-position: -200% 0; }
}

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

/* ---------- footer note ---------- */

.footnote {
    margin-top: 20px;
    padding: 12px var(--gutter);
    background: var(--white);
    border-top: 1px solid var(--border);
    display: flex;
    gap: 10px;
    align-items: center;
    font-size: 12px;
    color: var(--text-2);
    line-height: 1.35;
}

.footnote__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--brand); flex: none; }

.legal {
    padding: 16px var(--gutter) 24px;
    display: flex;
    gap: 16px;
    justify-content: center;
    font-size: 12px;
    color: var(--meta);
}

.legal a { min-height: 44px; display: flex; align-items: center; }

/* ---------- WhatsApp message preview (artboard 1e) ---------- */

.wa-preview { background: #E5DDD5; border-radius: var(--r-lg); padding: 16px; }

.wa-bubble {
    background: #DCF8C6;
    border-radius: 10px 0 10px 10px;
    padding: 10px 12px;
    font-size: 13px;
    line-height: 1.5;
    white-space: pre-line;
    color: #1B1916;
    margin-left: 24px;
}

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* ---------- product options: pick sizes, pick colours, price the combinations ----------

   The merchant thinks in three steps and the section is now built as three: which sizes, which
   colours, then what each combination costs. The combinations are written by the page as the first
   two are answered, because a shop stocking four sizes in three colours should not be twelve
   separate acts of data entry.

   Everything here reuses the chips and swatches already defined above. What is new is the affixed
   number field and the combination row, both of which exist to answer questions a bare number box
   left open: which currency, and how many of what. */

.picker { display: flex; flex-direction: column; gap: 8px; }

.picker__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
}

.picker__count { font-size: 13px; color: var(--text-2); }

/* An empty size list is a consequence of not having chosen a category, and silence there reads as a
   broken page. */
.picker__empty {
    font-size: 14px;
    color: var(--text-2);
    background: var(--surface-3);
    border: 1px dashed var(--border-2);
    border-radius: var(--r-md);
    padding: 12px;
}

/* A number that means money or quantity, with the unit attached to the field rather than floating
   in a placeholder that vanishes the moment you type. */
.affix {
    display: flex;
    align-items: stretch;
    border: 1.5px solid var(--border);
    border-radius: var(--r-md);
    background: var(--white);
    overflow: hidden;
    min-width: 0;
    flex: 1;
}

.affix:focus-within { outline: 2px solid var(--brand); outline-offset: 1px; }

.affix__unit {
    display: flex;
    align-items: center;
    padding: 0 10px;
    background: var(--surface-2);
    color: var(--text-2);
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
}

.affix__unit--trail { border-left: 1px solid var(--border); }
.affix__unit:not(.affix__unit--trail) { border-right: 1px solid var(--border); }

/* Wins over .optrow__line input, which would otherwise draw a second border inside the frame. */
.optrow__line .affix input,
.combo__line .affix input,
.affix input {
    border: 0;
    background: transparent;
    min-height: 44px;
    padding: 8px 10px;
    width: 100%;
    min-width: 0;
}

.affix input:focus { outline: none; }

/* One stocked combination. The size and colour are settled by the pickers above, so they are shown
   rather than re-asked; only the price and the count are still open questions. */
.combo {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px;
    border-bottom: 1px solid var(--border);
}

.combo:last-child { border-bottom: none; }

.combo__head { display: flex; align-items: center; gap: 8px; }

.combo__name { font-weight: 600; font-size: 15px; flex: 1; min-width: 0; }

.combo__swatch {
    width: 20px;
    height: 20px;
    border-radius: 10px;
    flex: none;
    border: 1px solid rgba(27, 25, 22, .14);
}

.combo__drop {
    flex: none;
    min-height: 44px;
    min-width: 44px;
    border: 0;
    background: transparent;
    color: var(--text-2);
    font-size: 20px;
    line-height: 1;
    border-radius: var(--r-md);
    cursor: pointer;
}

.combo__drop:hover { color: var(--ink); background: var(--surface-2); }

.combo__line { display: flex; gap: 8px; align-items: stretch; }

/* Applies one price and one count to every row, so a merchant who charges the same for all of them
   answers once. */
.applyall {
    display: flex;
    gap: 8px;
    align-items: stretch;
    padding: 12px;
    border-bottom: 1px solid var(--border);
    background: var(--surface-3);
    flex-wrap: wrap;
}

.applyall .affix { flex: 1 1 120px; }

.applyall__go {
    flex: none;
    min-height: 44px;
    padding: 0 14px;
    border-radius: var(--r-md);
    border: 1.5px solid var(--border-2);
    background: var(--white);
    font-weight: 600;
    cursor: pointer;
}

.applyall__go:hover { border-color: var(--ink); }

/* ---------- work in progress ----------

   The editor swaps pages without reloading, which removed the browser's own loading indicator and
   replaced it with nothing: a merchant pressed "Add product", the photo uploaded for a few seconds,
   and the page sat still. This is the bar that says something is happening. The pressed button also
   changes its own label, which is the part people actually look at. */

body[aria-busy="true"]::before {
    content: "";
    position: fixed;
    inset: 0 0 auto 0;
    height: 3px;
    z-index: 50;
    background: linear-gradient(90deg, transparent, var(--brand), transparent);
    background-size: 40% 100%;
    background-repeat: no-repeat;
    animation: duka-progress 1.1s ease-in-out infinite;
}

@keyframes duka-progress {
    0%   { background-position: -40% 0; }
    100% { background-position: 140% 0; }
}

/* A moving bar is exactly what some people cannot tolerate; the bar stays, the movement goes. */
@media (prefers-reduced-motion: reduce) {
    body[aria-busy="true"]::before {
        animation: none;
        background: var(--brand);
        opacity: .6;
    }
}

button[disabled] { cursor: progress; }

/* Secondary next to the share actions: it is a step, not the headline. */
.cta--inline {
    display: inline-block;
    width: auto;
    padding: 0.7rem 1.1rem;
    min-height: 44px;
}

/* ---------- drafts: what a model proposed, waiting for a person ---------- */

/*
   The review screen is the add-product form with three things added: the photograph it was read
   from, a note when the reading needs explaining, and a mark on every field the merchant should
   look at twice. Everything else - the fields, the pickers, the swatches - is the same markup and
   the same CSS, because a merchant should not have to learn a second form.

   The mark is warm, not red. Nothing has gone wrong; the merchant is simply the one who decides,
   and a screen they see twenty times in a row should not look like twenty errors.
*/

:root {
    /* 5.75:1 on its own background, so the chip is readable rather than decorative. */
    --check: #7A5A12;
    --check-bg: #FAF3E2;
    /* 3.1:1 on white, against the ordinary field border's 1.3:1 - a flagged field has to be
       distinguishable from an unflagged one at arm's length in daylight, not just up close. */
    --check-line: #B08E3C;
}

/* A block of content in the page gutter that does not claim the remaining height, unlike .page.
   Used for the notices that sit above the form: an error, a confirmation, the reading progress. */
.strip {
    padding: 14px var(--gutter) 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* Prose inside a panel. .panel itself is deliberately unpadded - it holds .line rows that carry
   their own - so text put straight into one sits on the border, which is what it did. */
.panel--pad { padding: var(--gutter); }

.progress {
    height: 6px;
    border-radius: var(--r-pill);
    background: var(--surface-2);
    overflow: hidden;
}

.progress__bar {
    height: 100%;
    background: var(--brand);
    border-radius: var(--r-pill);
    transition: width 400ms ease;
}

@media (prefers-reduced-motion: reduce) {
    .progress__bar { transition: none; }
}

/* One tick per product in the batch, filled as the merchant works through it. A bar rather than
   "3 of 14" alone: the count is in the header, and this says how much is left without reading. */
.stepper-rail {
    display: flex;
    gap: 3px;
    padding: 10px var(--gutter) 0;
}

.stepper-rail__tick {
    flex: 1;
    height: 3px;
    border-radius: var(--r-pill);
    background: var(--border);
}

.stepper-rail__tick--done { background: var(--brand); }
.stepper-rail__tick--now { background: var(--ink); }

.draft__photo {
    border-radius: var(--r-lg);
    overflow: hidden;
    background: var(--surface-2);
    border: 1px solid var(--border);
    aspect-ratio: 4 / 5;
    max-height: 280px;
}

.draft__photo img { width: 100%; height: 100%; object-fit: contain; }

/* What the model could not do, in the merchant's terms. Sits above the fields it explains. */
.draft__note {
    font-size: 13px;
    color: var(--text-2);
    background: var(--surface-3);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    padding: 10px 12px;
    margin: 0;
}

.draft__flag {
    font-size: 11px;
    font-weight: 600;
    color: var(--check);
    background: var(--check-bg);
    border: 1px solid var(--check-line);
    border-radius: var(--r-pill);
    padding: 1px 7px;
    margin-left: 6px;
    white-space: nowrap;
}

.field--check input,
.field--check select,
.field--check textarea { border-color: var(--check-line); background: #FFFDF8; }

/* Two buttons that mean opposite things, stacked so they are never close enough to mistap. */
.decide { display: flex; flex-direction: column; gap: 10px; }

/* ---------- choosing files ---------- */

/*
   A browser's own file input renders as "Choose Files / No file chosen" in the platform's button
   style, which on this screen was the only control that did not look like the rest of the shop and
   the only one that never said what had been picked. The real input is still there and still does
   the work; it is just behind a panel the whole width of the thumb.
*/

.dropzone {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: 22px var(--gutter);
    border: 1.5px dashed var(--border-2);
    border-radius: var(--r-lg);
    background: var(--white);
    text-align: center;
    cursor: pointer;
}

.dropzone:focus-within {
    border-color: var(--brand);
    border-style: solid;
    outline: 2px solid var(--brand);
    outline-offset: 2px;
}

.dropzone__glyph {
    width: 26px;
    height: 22px;
    border: 1.5px solid var(--muted);
    border-radius: var(--r-sm);
    position: relative;
}

/* A photograph: a horizon and a sun, drawn rather than shipped as an image. */
.dropzone__glyph::before {
    content: "";
    position: absolute;
    inset: auto 3px 3px 3px;
    height: 7px;
    border-radius: 2px 2px var(--r-sm) var(--r-sm);
    background: var(--muted);
}

.dropzone__glyph::after {
    content: "";
    position: absolute;
    top: 4px;
    right: 5px;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--muted);
}

/* A file: one corner turned. */
.dropzone__glyph--file { width: 20px; height: 24px; }
.dropzone__glyph--file::before { inset: auto 4px 4px 4px; height: 2px; border-radius: 0; }
.dropzone__glyph--file::after {
    top: 0;
    right: 0;
    width: 0;
    height: 0;
    border-radius: 0;
    background: none;
    border-top: 7px solid var(--surface-2);
    border-left: 7px solid transparent;
}

.dropzone__label { font-weight: 600; }
.dropzone__hint { font-size: 12px; color: var(--meta); }

/* A worked example of the file we are asking for, shown rather than described. Scrolls on its own
   rather than wrapping: a CSV line broken across three lines stops looking like a CSV line. */
.sample {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 10px 12px;
    border-radius: var(--r-md);
    background: var(--surface-2);
    overflow-x: auto;
}

.sample__row {
    font-family: ui-monospace, "Cascadia Mono", "Roboto Mono", monospace;
    font-size: 12px;
    color: var(--text-2);
    white-space: nowrap;
}

.sample__row--head { color: var(--ink); font-weight: 600; }

/* Separates two alternatives. Not a shadow and not a card - a line, like everything else here. */
.rule {
    border: none;
    border-top: 1px solid var(--border);
    margin: 2px 0;
}
