/* ============================================================
   AL FAN — Design System Tokens & Storefront Components
   Ported from the approved design prototype (Prototype/shared/tokens.css
   + customer/customer.css), which implements 04_Design_System.docx.

   IMPORTANT — why the component layer is scoped under `.af`:
   the storefront's existing pages each carry their own <style> block and
   define generic names (.btn, .card, .badge, .grid, .state, .row, .input)
   with different rules per page, and none of them were authored against a
   reset. A global component layer would collide with all of them. Scoping
   under `.af` means a page opts in by adding the class to its root element,
   and every page that has not been migrated is completely unaffected.

   The :root tokens below are global and purely additive - any page can
   start consuming them immediately without opting in.
   ============================================================ */

:root {
    /* Brand core */
    --red: #A6192E;
    --red-dark: #7A1220;
    --red-tint: #FBEFF1;
    --grey: #3B3B3B;
    --grey-mid: #6E6E6E;
    --grey-light: #E9E7E5;
    --grey-pale: #F4F3F1;
    --white: #FFFFFF;
    --black: #1A1A1A;

    /* Semantic */
    --success: #2E7D32;
    --success-tint: #EAF4EB;
    --warning: #B8860B;
    --warning-tint: #FAF3E0;
    --error: #A6192E;
    --info: #2E5C8A;
    --info-tint: #EAF0F6;

    /* Spacing scale (8px base) */
    --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
    --s5: 24px; --s6: 32px; --s7: 48px; --s8: 64px;

    /* Type */
    --font: 'Segoe UI', 'Inter', -apple-system, system-ui, sans-serif;
    --font-ar: 'Segoe UI', 'Noto Kufi Arabic', 'IBM Plex Sans Arabic', sans-serif;

    --radius: 10px;
    --radius-sm: 6px;
    --shadow-1: 0 1px 3px rgba(26, 26, 26, .08);
    --shadow-2: 0 4px 16px rgba(26, 26, 26, .12);
    --shadow-3: 0 12px 40px rgba(26, 26, 26, .18);
    --maxw: 1240px;
    --trans: 200ms cubic-bezier(.4, 0, .2, 1);
}

/* ---------- scoped reset (opt-in) ---------- */
.af, .af *, .af *::before, .af *::after { box-sizing: border-box; }
.af h1, .af h2, .af h3, .af h4, .af h5, .af p { margin: 0; }
.af img { max-width: 100%; display: block; }
.af a { color: inherit; text-decoration: none; }
.af button { font-family: inherit; cursor: pointer; }
.af { font-family: var(--font); color: var(--black); }
html[dir="rtl"] .af { font-family: var(--font-ar); }

/* ---------- type scale ---------- */
.af .t-display { font-size: 32px; line-height: 40px; font-weight: 700; }
.af .t-h1 { font-size: 26px; line-height: 32px; font-weight: 700; }
.af .t-h2 { font-size: 21px; line-height: 28px; font-weight: 600; }
.af .t-h3 { font-size: 17px; line-height: 24px; font-weight: 600; }
.af .t-body { font-size: 15px; line-height: 22px; }
.af .t-small { font-size: 13px; line-height: 18px; color: var(--grey-mid); }
.af .t-price { font-size: 19px; line-height: 24px; font-weight: 700; }
.af .t-label { font-size: 12px; line-height: 16px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; }
.af .muted { color: var(--grey-mid); }

/* ---------- buttons ---------- */
.af .btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    border: none; border-radius: var(--radius-sm); cursor: pointer;
    font-family: inherit; font-size: 14px; font-weight: 700;
    padding: 12px 22px; transition: background var(--trans), transform var(--trans);
}
.af .btn-primary { background: var(--red); color: #fff; }
.af .btn-primary:hover { background: var(--red-dark); }
.af .btn-secondary { background: #fff; color: var(--black); border: 1.5px solid var(--grey-light); }
.af .btn-secondary:hover { border-color: var(--red); color: var(--red); }
.af .btn-dark { background: var(--grey); color: #fff; }
.af .btn-sm { padding: 8px 14px; font-size: 13px; }
.af .btn:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }

/* ---------- badges ---------- */
.af .badge {
    display: inline-flex; align-items: center; gap: 4px;
    font-size: 11px; font-weight: 700; letter-spacing: .04em;
    padding: 3px 9px; border-radius: 999px; text-transform: uppercase;
}
.af .badge-sale { background: var(--red); color: #fff; }
.af .badge-new { background: var(--black); color: #fff; }
.af .badge-loyalty { background: linear-gradient(90deg, #F0C040, #DBA514); color: #4A3600; }
.af .badge-oos { background: var(--grey-mid); color: #fff; }
.af .badge-success { background: var(--success-tint); color: var(--success); }

/* ---------- section heading ---------- */
.af .sec-head { display: flex; align-items: baseline; justify-content: space-between; margin: var(--s5) 0 var(--s3); gap: var(--s3); }
.af .sec-head a { font-size: 13.5px; font-weight: 600; color: var(--red); }
.af .sec-head a:hover { text-decoration: underline; }

/* ---------- product card ---------- */
.af .pcard { position: relative; }
.af .pcard .imgbox { position: relative; border-radius: var(--radius); overflow: hidden; background: var(--grey-pale); }
.af .pcard img { aspect-ratio: 1/1; width: 100%; object-fit: cover; transition: transform .5s ease; }
.af .pcard:hover img { transform: scale(1.04); }
.af .pcard .imgbox .ph { aspect-ratio: 1/1; display: grid; place-items: center; font-size: 40px; font-weight: 800; color: var(--grey-light); }
.af .pcard .badge { position: absolute; top: 10px; inset-inline-start: 10px; z-index: 1; }
.af .pcard .binfo { padding: 10px 2px 0; }
.af .pcard .bname { font-size: 12px; color: var(--grey-mid); font-weight: 600; text-transform: uppercase; letter-spacing: .05em; }
.af .pcard .pname { font-size: 14px; margin: 3px 0 5px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.af .pcard .prices { display: flex; gap: 8px; align-items: baseline; font-weight: 700; font-size: 15px; }
.af .pcard .prices .was { text-decoration: line-through; color: var(--grey-mid); font-weight: 400; font-size: 12.5px; }
.af .pcard .prices .now.sale { color: var(--red); }
.af .pcard .pts { font-size: 11.5px; color: var(--warning); font-weight: 600; margin-top: 4px; }
.af .pcard .stars { font-size: 12px; color: var(--warning); letter-spacing: .04em; margin: 2px 0 4px; }
.af .pcard .stars .muted { color: var(--grey-mid); font-size: 11.5px; }
.af .pcard .lowstock { font-size: 11.5px; color: var(--red); font-weight: 600; margin-top: 3px; }
/* Sold-out items stay legible but visibly de-emphasised, rather than being hidden. */
.af .pcard .oos-cover { position: absolute; inset: 0; background: rgba(255, 255, 255, .55); pointer-events: none; }

/* ---------- horizontal carousel ---------- */
.af .hwrap { position: relative; }
.af .hscroll {
    /* Track width is a fraction of the row, NOT 1fr. With 1fr a three-item carousel
       stretched each card to ~400px and read as three billboards; with a fixed cap it
       left most of the row empty. Sizing by --cols keeps cards card-sized whether the
       carousel holds three items or thirty, and still scrolls once it overflows. */
    --cols: 5;
    display: grid; grid-auto-flow: column;
    grid-auto-columns: calc((100% - (var(--cols) - 1) * var(--s4)) / var(--cols));
    justify-content: start;
    gap: var(--s4); overflow-x: auto; scroll-snap-type: x mandatory;
    scrollbar-width: none; padding-bottom: 4px;
}
@media (max-width: 1100px) { .af .hscroll { --cols: 4; } }
@media (max-width: 860px)  { .af .hscroll { --cols: 3; } }
@media (max-width: 620px)  { .af .hscroll { --cols: 2.2; } }
.af .hscroll::-webkit-scrollbar { display: none; }
.af .hscroll .pcard { scroll-snap-align: start; }
.af .hwrap .harr {
    position: absolute; top: 34%; z-index: 2; width: 38px; height: 38px;
    border-radius: 50%; border: 1px solid var(--grey-light); background: #fff;
    font-size: 20px; line-height: 1; color: var(--grey);
    display: grid; place-items: center; box-shadow: var(--shadow-1);
    transition: transform var(--trans), color var(--trans);
}
.af .hwrap .harr:hover { transform: scale(1.1); color: var(--red); }
.af .hwrap .harr.prev { inset-inline-start: -12px; }
.af .hwrap .harr.next { inset-inline-end: -12px; }
@media (max-width: 700px) { .af .hwrap .harr { display: none; } }

/* ---------- hero slider ---------- */
.af .slider { position: relative; margin-top: var(--s5); }
.af .slides {
    display: grid; grid-auto-flow: column; grid-auto-columns: 100%;
    overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none;
    border-radius: 16px;
}
.af .slides::-webkit-scrollbar { display: none; }
.af .slide { position: relative; scroll-snap-align: start; cursor: pointer; }
.af .slide img { width: 100%; aspect-ratio: 1280/440; object-fit: cover; }
.af .slide .ph { width: 100%; aspect-ratio: 1280/440; background: var(--grey-pale); }
.af .hero-ov {
    position: absolute; inset-inline-start: 0; bottom: 0; width: 100%;
    padding: clamp(18px, 4vw, 44px);
    background: linear-gradient(0deg, rgba(0, 0, 0, .62), transparent);
    color: #fff;
}
.af .hero-ov h2 { font-size: clamp(20px, 3.4vw, 34px); font-weight: 800; margin-bottom: 12px; text-shadow: 0 2px 12px rgba(0, 0, 0, .35); }
.af .slider .arr {
    position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
    width: 42px; height: 42px; border-radius: 50%; border: none;
    background: rgba(255, 255, 255, .82); color: var(--black);
    font-size: 22px; line-height: 1; display: grid; place-items: center;
    box-shadow: var(--shadow-2); transition: transform var(--trans), background var(--trans);
}
.af .slider .arr:hover { background: #fff; transform: translateY(-50%) scale(1.08); }
.af .slider .arr.prev { inset-inline-start: 14px; }
.af .slider .arr.next { inset-inline-end: 14px; }
.af .dots { position: absolute; bottom: 14px; inset-inline: 0; display: flex; gap: 7px; justify-content: center; z-index: 2; }
.af .dots i { width: 8px; height: 8px; border-radius: 50%; background: rgba(255, 255, 255, .5); transition: all var(--trans); cursor: pointer; }
.af .dots i.on { background: #fff; width: 22px; border-radius: 4px; }

/* ---------- category story circles ---------- */
.af .stories { display: flex; gap: clamp(10px, 2.5vw, 26px); overflow-x: auto; padding: var(--s5) 2px var(--s4); scrollbar-width: none; justify-content: center; }
.af .stories::-webkit-scrollbar { display: none; }
.af .story { flex: 0 0 auto; text-align: center; width: 86px; }
.af .story .ring {
    width: 78px; height: 78px; border-radius: 50%; padding: 3px; margin: 0 auto 8px;
    background: linear-gradient(135deg, var(--red), #E86A7C);
    transition: transform var(--trans);
}
.af .story:hover .ring { transform: scale(1.08) rotate(3deg); }
.af .story .ring img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; border: 3px solid #fff; }
.af .story .ring .ph { width: 100%; height: 100%; border-radius: 50%; border: 3px solid #fff; background: var(--grey-pale); display: grid; place-items: center; font-weight: 800; color: var(--grey-mid); }
.af .story span { font-size: 12.5px; font-weight: 600; color: var(--grey); display: block; }

/* ---------- flash sale strip ---------- */
.af .flash {
    margin-top: var(--s5); border-radius: 16px; overflow: hidden; position: relative;
    background: linear-gradient(120deg, #2A2A2A, #4A1420);
    color: #fff; padding: clamp(18px, 3vw, 28px);
    display: flex; align-items: center; justify-content: space-between; gap: var(--s4); flex-wrap: wrap;
}
.af .flash::before, .af .flash::after { content: ""; position: absolute; border-radius: 50%; }
.af .flash::before { width: 240px; height: 240px; background: var(--red); top: -120px; inset-inline-end: 8%; opacity: .35; }
.af .flash::after { width: 180px; height: 180px; background: #ffffff22; bottom: -90px; inset-inline-start: 20%; }
.af .flash h3 { font-size: clamp(17px, 2.4vw, 24px); font-weight: 800; z-index: 1; position: relative; }
.af .flash .sub { color: rgba(255, 255, 255, .75); font-size: 13px; margin-top: 3px; z-index: 1; position: relative; }
.af .timer { display: flex; gap: 8px; align-items: center; z-index: 1; }
.af .timer .cell { background: rgba(255, 255, 255, .12); border-radius: 8px; padding: 8px 12px; text-align: center; min-width: 56px; }
.af .timer .cell b { display: block; font-size: 22px; font-variant-numeric: tabular-nums; }
.af .timer .cell span { font-size: 10px; text-transform: uppercase; letter-spacing: .08em; color: rgba(255, 255, 255, .65); }
.af .timer .sep { font-size: 20px; font-weight: 800; opacity: .5; }

/* ---------- mosaic ---------- */
.af .mosaic { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr); gap: var(--s4); margin-top: var(--s4); }
.af .mosaic .cell { position: relative; border-radius: 16px; overflow: hidden; }
.af .mosaic .cell img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s ease; }
.af .mosaic .cell:hover img { transform: scale(1.04); }
.af .mosaic .tall { grid-row: span 2; }
.af .mosaic .tall img { aspect-ratio: 3/4; }
.af .mosaic .wide img { aspect-ratio: 16/6.4; }
.af .mosaic .cell .cap {
    position: absolute; inset-inline-start: 0; bottom: 0; width: 100%; padding: 18px;
    background: linear-gradient(0deg, rgba(0, 0, 0, .55), transparent); color: #fff;
}
.af .mosaic .cell .cap h3 { font-size: clamp(15px, 1.8vw, 21px); font-weight: 800; text-shadow: 0 1px 8px rgba(0, 0, 0, .4); }
.af .mosaic .cell .cap span { font-size: 12.5px; color: rgba(255, 255, 255, .85); }
@media (max-width: 800px) { .af .mosaic { grid-template-columns: 1fr; } .af .mosaic .tall { grid-row: auto; } }

/* ---------- loyalty band ---------- */
.af .loyal-band {
    margin-top: var(--s5); border-radius: 20px; position: relative; overflow: hidden;
    background: linear-gradient(120deg, #241F1F, #4A1420);
    color: #fff; padding: clamp(22px, 4vw, 44px);
    display: grid; grid-template-columns: 1.4fr 1fr; gap: var(--s5); align-items: center;
}
.af .loyal-band::before { content: "★"; position: absolute; font-size: 300px; inset-inline-end: -50px; top: -80px; opacity: .06; line-height: 1; }
.af .loyal-band h2 { font-size: clamp(20px, 3vw, 30px); font-weight: 800; line-height: 1.2; }
.af .loyal-band p { color: rgba(255, 255, 255, .72); margin-top: 8px; font-size: 14px; }
.af .loyal-band .glass {
    background: rgba(255, 255, 255, .09); border: 1px solid rgba(255, 255, 255, .16);
    border-radius: 16px; padding: 22px; backdrop-filter: blur(6px); text-align: center;
}
.af .loyal-band .pts {
    font-size: clamp(30px, 4vw, 44px); font-weight: 800;
    background: linear-gradient(90deg, #F0C040, #DBA514);
    -webkit-background-clip: text; background-clip: text; color: transparent;
}
@media (max-width: 800px) { .af .loyal-band { grid-template-columns: 1fr; } }

/* ---------- two-up strip ---------- */
.af .strip2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s4); margin-top: var(--s4); }
.af .strip2 .cell { position: relative; border-radius: 16px; overflow: hidden; }
.af .strip2 .cell img { width: 100%; aspect-ratio: 4/3; object-fit: cover; object-position: top; }
@media (max-width: 700px) { .af .strip2 { grid-template-columns: 1fr; } }

/* ---------- product grid ---------- */
.af .pgrid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s5) var(--s4); }
@media (max-width: 980px) { .af .pgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 700px) { .af .pgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ---------- site header ---------- */
.af.sitehd { max-width: var(--maxw); margin: 0 auto; padding: 14px 20px 0; }
.af .hdmain { display: flex; align-items: center; gap: var(--s5); }

.af .hdsearch { flex: 1; max-width: 460px; position: relative; display: flex; align-items: center; }
.af .hdsearch .ic { position: absolute; inset-inline-start: 12px; color: var(--grey-mid); display: flex; pointer-events: none; }
.af .hdsearch .sinput {
    width: 100%; font-family: inherit; font-size: 13.5px;
    padding: 9px 14px 9px 40px; border: 1.5px solid var(--grey-light);
    border-radius: 999px; background: var(--grey-pale); color: var(--black);
}
html[dir="rtl"] .af .hdsearch .sinput { padding: 9px 40px 9px 14px; }
.af .hdsearch .sinput:focus { outline: none; border-color: var(--red); background: #fff; }

/* ---------- search suggestions ---------- */
/* The panel hangs off .hdsearch, which is already position:relative. Logical properties
   throughout, so it flips with the document rather than needing an RTL variant. */
.af .hdsg {
    position: absolute; inset-block-start: calc(100% + 6px); inset-inline: 0;
    z-index: 130; background: #fff; border: 1px solid var(--grey-light);
    border-radius: 14px; box-shadow: 0 12px 32px rgba(26, 26, 26, .14);
    padding: 6px 0; max-height: 70vh; overflow-y: auto; text-align: start;
}
.af .hdsg-h {
    font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
    color: var(--grey-mid); padding: 8px 14px 4px;
}
.af .hdsg-r {
    display: flex; align-items: center; gap: 10px; padding: 8px 14px;
    color: var(--black); font-size: 13.5px; line-height: 1.3;
}
.af .hdsg-r:hover, .af .hdsg-r:focus-visible { background: var(--grey-pale); }
.af .hdsg-ic { display: flex; color: var(--grey-mid); flex: none; }
.af .hdsg-th {
    width: 38px; height: 38px; flex: none; border-radius: 8px; overflow: hidden;
    background: var(--grey-pale); display: flex; align-items: center; justify-content: center;
}
.af .hdsg-th img { width: 100%; height: 100%; object-fit: cover; }
.af .hdsg-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.af .hdsg-nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.af .hdsg-sub { font-size: 11.5px; color: var(--grey-mid); }
.af .hdsg-p { font-size: 12.5px; font-weight: 700; flex: none; }
.af .hdsg-n { font-size: 11.5px; color: var(--grey-mid); flex: none; }
/* The category rows are the reason this panel exists, so they read as the primary action. */
.af .hdsg-cat .hdsg-t { font-weight: 600; }
.af .hdsg-none { padding: 14px; font-size: 13px; color: var(--grey-mid); }
.af .hdsg-all {
    display: block; padding: 10px 14px; margin-top: 4px;
    border-top: 1px solid var(--grey-light);
    font-size: 12.5px; font-weight: 700; color: var(--red);
}
.af .hdsg-all:hover { background: var(--grey-pale); }
/* Invisible, full-viewport, and behind the panel: it exists only to catch the click that
   closes it, which is why it carries no visual weight of its own. */
.af .hdsg-scrim {
    position: fixed; inset: 0; z-index: 125;
    border: 0; padding: 0; margin: 0; background: transparent; cursor: default;
}

.af .sitenav { display: flex; align-items: center; gap: var(--s4); margin-inline-start: auto; }
.af .sitenav a { color: var(--grey-mid); font-size: 13.5px; font-weight: 600; }
.af .sitenav a:hover { color: var(--red); }
.af .sitenav .hicon { display: inline-flex; align-items: center; position: relative; }
.af .sitehd .badge {
    background: var(--red); color: #fff; font-size: 10.5px; font-weight: 700;
    min-width: 16px; height: 16px; border-radius: 8px; padding: 0 4px;
    display: inline-flex; align-items: center; justify-content: center;
    position: absolute; top: -6px; inset-inline-end: -8px; text-transform: none; letter-spacing: 0;
}
.af .langsw { border-inline-start: 1px solid var(--grey-light); padding-inline-start: var(--s4); }

.af .catnav {
    display: flex; gap: var(--s5); overflow-x: auto; scrollbar-width: none;
    margin-top: var(--s3); padding-bottom: 10px; border-bottom: 1px solid var(--grey-light);
}
.af .catnav::-webkit-scrollbar { display: none; }
.af .catnav a { font-size: 13px; font-weight: 600; color: var(--grey); white-space: nowrap; }
.af .catnav a:hover { color: var(--red); }

@media (max-width: 760px) {
    .af .hdmain { flex-wrap: wrap; }
    .af .hdsearch { order: 3; flex-basis: 100%; max-width: none; margin-top: 10px; }
    .af .sitenav .langsw { border: 0; padding-inline-start: 0; }
}

/* ---------- cart drawer ---------- */
.af.cdrawer-wrap { position: fixed; inset: 0; z-index: 120; }
.af .cdrawer-scrim {
    position: absolute; inset: 0; border: 0; padding: 0; cursor: default;
    background: rgba(26, 26, 26, .45); animation: af-fade .2s ease;
}
@keyframes af-fade { from { opacity: 0; } }

.af .cdrawer {
    position: absolute; inset-block: 0; inset-inline-end: 0;
    width: min(400px, 100%); background: #fff;
    display: flex; flex-direction: column;
    box-shadow: var(--shadow-3);
    animation: af-slidein .26s cubic-bezier(.2, .9, .3, 1);
}
@keyframes af-slidein { from { transform: translateX(100%); } }
html[dir="rtl"] .af .cdrawer { animation-name: af-slidein-rtl; }
@keyframes af-slidein-rtl { from { transform: translateX(-100%); } }

.af .cdrawer-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 16px 20px; border-bottom: 1px solid var(--grey-light); flex: none;
}
.af .cclose { background: none; border: 0; font-size: 17px; color: var(--grey-mid); line-height: 1; padding: 4px; }
.af .cclose:hover { color: var(--red); }

.af .cdrawer-body { flex: 1; overflow-y: auto; padding: 8px 20px; }
.af .cerr { background: var(--red-tint); color: var(--red); padding: 10px 12px; border-radius: var(--radius-sm); font-size: 13px; margin: 10px 0; }

.af .cline { display: flex; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--grey-pale); }
.af .cthumb { flex: none; width: 62px; border-radius: var(--radius-sm); overflow: hidden; background: var(--grey-pale); }
.af .cthumb img { width: 100%; aspect-ratio: 4/5; object-fit: cover; }
.af .cthumb .ph { display: grid; place-items: center; aspect-ratio: 4/5; font-weight: 800; color: var(--grey-mid); }
.af .cinfo { flex: 1; min-width: 0; }
.af .cname { font-size: 13.5px; font-weight: 600; color: var(--black); }
.af .cmeta { margin-top: 2px; }
.af .crow { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 8px; }
.af .cqty { display: inline-flex; align-items: center; gap: 10px; border: 1px solid var(--grey-light); border-radius: 999px; padding: 2px 8px; }
.af .cqty .stepbtn { background: none; border: 0; font-size: 15px; color: var(--grey); line-height: 1; padding: 2px 4px; }
.af .cqty .stepbtn:hover:not(:disabled) { color: var(--red); }
.af .cqty .stepbtn:disabled { opacity: .4; cursor: default; }
.af .cprice { font-size: 13.5px; }
.af .cremove { background: none; border: 0; color: var(--grey-mid); font-size: 13px; align-self: flex-start; padding: 2px 4px; }
.af .cremove:hover:not(:disabled) { color: var(--red); }

.af .cempty { text-align: center; padding: 60px 20px; color: var(--grey-mid); }
.af .cempty .art { display: flex; justify-content: center; margin-bottom: 12px; color: var(--grey-light); }
.af .cempty .art svg { width: 44px; height: 44px; }
.af .cempty .btn { margin-top: 16px; }

.af .cdrawer-foot { flex: none; border-top: 1px solid var(--grey-light); padding: 16px 20px; display: flex; flex-direction: column; gap: 8px; }
.af .csub { display: flex; justify-content: space-between; align-items: baseline; font-size: 15px; }
.af .csub b { font-size: 17px; }
.af .btn-block { width: 100%; }

@media (prefers-reduced-motion: reduce) {
    .af .cdrawer, .af .cdrawer-scrim { animation: none; }
}

/* ---------- mobile tab bar ---------- */
.af.tabbar { display: none; }

@media (max-width: 760px) {
    .af.tabbar {
        display: grid; grid-template-columns: repeat(4, 1fr);
        position: fixed; inset-inline: 0; bottom: 0; z-index: 80;
        background: #fff; border-top: 1px solid var(--grey-light);
        /* Respect the iOS home indicator rather than sitting under it. */
        padding-bottom: env(safe-area-inset-bottom, 0px);
    }
    .af.tabbar a {
        display: flex; flex-direction: column; align-items: center; gap: 3px;
        padding: 9px 4px; font-size: 10.5px; font-weight: 600; color: var(--grey-mid);
    }
    .af.tabbar a.on { color: var(--red); }
    .af.tabbar .ic { position: relative; display: flex; }
    .af.tabbar .badge {
        position: absolute; top: -5px; inset-inline-end: -9px;
        background: var(--red); color: #fff; font-size: 9.5px; font-weight: 700;
        min-width: 15px; height: 15px; border-radius: 8px; padding: 0 3px;
        display: inline-flex; align-items: center; justify-content: center;
    }

    /* The prototype's tab bar covered page content - the customer's review called it
       out. Reserve the bar's height (plus safe area) so the last element on any page
       stays reachable. */
    body { padding-bottom: calc(58px + env(safe-area-inset-bottom, 0px)); }
}

/* ---------- customer account shell ---------- */
.af.acct .wrap { max-width: var(--maxw); margin: 0 auto; padding: 20px 20px 60px; }
.af .accthead { margin: 8px 0 var(--s5); }
.af .prof-grid { display: grid; grid-template-columns: 250px minmax(0, 1fr); gap: var(--s6); align-items: start; }
@media (max-width: 820px) { .af .prof-grid { grid-template-columns: 1fr; } }
.af .prof-nav { display: flex; flex-direction: column; gap: 2px; }
.af .prof-nav a {
    display: flex; align-items: center; gap: 10px;
    padding: 11px 14px; border-radius: var(--radius-sm);
    font-weight: 600; font-size: 14px; color: var(--grey);
    transition: background var(--trans), color var(--trans);
}
.af .prof-nav a:hover { background: var(--grey-pale); }
.af .prof-nav a.on { background: var(--red-tint); color: var(--red); }
.af .prof-nav a.out { color: var(--red); margin-top: var(--s3); }
.af .prof-nav a:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
.af .prof-nav .ic { display: flex; flex: none; }

/* ---------- generic surfaces used by the account/cart pages ---------- */
.af .card { background: #fff; border: 1px solid var(--grey-light); border-radius: var(--radius); }
.af .card-pad { padding: var(--s5); }
.af .state { text-align: center; padding: 64px 20px; color: var(--grey-mid); }
.af .state .art { font-size: 48px; }
.af .state h3 { color: var(--black); margin: 10px 0 6px; }
.af .state .btn { margin-top: 16px; }

/* ---------- footer ---------- */
.af-foot { border-top: 1px solid var(--grey-light); margin-top: var(--s6); background: var(--grey-pale); }
.af-foot .inner { max-width: var(--maxw); margin: 0 auto; padding: var(--s6) 20px var(--s5); }
.af-foot .foot-grid { display: grid; grid-template-columns: 2fr repeat(4, 1fr); gap: var(--s5); }
.af-foot h5 { font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--black); margin-bottom: 10px; }
.af-foot a { display: block; font-size: 13.5px; color: var(--grey-mid); padding: 3px 0; text-decoration: none; }
.af-foot a:hover { color: var(--red); }
.af-foot .afbrand { margin-bottom: 14px; }
.af-foot .blurb { font-size: 13px; line-height: 19px; color: var(--grey-mid); max-width: 42ch; }
.af-foot .note { border-top: 1px solid var(--grey-light); margin-top: var(--s5); padding-top: var(--s4); font-size: 12.5px; color: var(--grey-mid); }
@media (max-width: 1080px) { .af-foot .foot-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 800px) { .af-foot .foot-grid { grid-template-columns: 1fr 1fr; } }

/* ---------- scroll reveal ----------
   Progressive enhancement: the hidden state applies ONLY when JS is running
   (html.af-js is set by an inline script in App.razor before first paint). If
   storefront.js fails to load, or IntersectionObserver never fires, the page is
   never left with invisible content - it simply renders without the animation. */
html.af-js .af .rev { opacity: 0; transform: translateY(26px); }
html.af-js .af .rev-in { opacity: 1; transform: none; transition: opacity .7s ease, transform .7s cubic-bezier(.2, .8, .3, 1); }

/* ---------- skeletons ---------- */
.af .skel { position: relative; overflow: hidden; background: var(--grey-pale); border-radius: var(--radius-sm); }
.af .skel::after {
    content: ""; position: absolute; inset: 0;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .6), transparent);
    transform: translateX(-100%); animation: af-shimmer 1.4s infinite;
}
@keyframes af-shimmer { to { transform: translateX(100%); } }

.af .page-in { animation: af-pagein .3s ease; }
@keyframes af-pagein { from { opacity: 0; transform: translateY(10px); } }

@media (prefers-reduced-motion: reduce) {
    html.af-js .af .rev { opacity: 1; transform: none; }
    html.af-js .af .rev-in { transition: none; }
    .af .page-in { animation: none; }
    .af .skel::after { animation: none; }
    .af .marquee .track { animation: none; }
}

/* ---------- brand marquee ---------- */
.af .marquee { overflow: hidden; margin-top: var(--s5); border-block: 1px solid var(--grey-light); padding: 18px 0; }
.af .marquee .track { display: flex; gap: 64px; width: max-content; animation: af-marquee 26s linear infinite; }
.af .marquee:hover .track { animation-play-state: paused; }
.af .marquee .br {
    font-size: 21px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
    color: var(--grey-light); white-space: nowrap; transition: color var(--trans);
}
.af .marquee .br:hover { color: var(--red); }
.af .marquee .br i { font-style: normal; color: var(--red); opacity: .5; margin-inline: 26px; }
@keyframes af-marquee { to { transform: translateX(-50%); } }

/* ============================================================================
   Image crop dialog (.afcrop)

   NOT nested under .af. The storefront component layer is scoped so it cannot
   collide with the pages' own <style> blocks, but this dialog is used from the
   ADMIN pages, which never carry .af. It gets its own prefix instead, and every
   rule below is prefixed, so it stays just as collision-proof.
   ============================================================================ */
.afcrop-wrap { position: fixed; inset: 0; z-index: 900; display: flex;
               align-items: center; justify-content: center; padding: 20px; }
.afcrop-scrim { position: absolute; inset: 0; background: rgba(20,20,20,.62); }

.afcrop { position: relative; display: flex; flex-direction: column;
          width: min(880px, 100%); max-height: 100%; background: #fff;
          border-radius: 10px; box-shadow: 0 24px 60px rgba(0,0,0,.32);
          font: 400 14px/1.45 system-ui, -apple-system, "Segoe UI", sans-serif;
          color: #1F1F1F; overflow: hidden; }
.afcrop * { box-sizing: border-box; }

.afcrop-head { display: flex; align-items: center; gap: 12px;
               padding: 14px 18px; border-bottom: 1px solid #E7E7E7; }
.afcrop-title { flex: 1; font-size: 15px; font-weight: 600; }
.afcrop-x { border: 0; background: none; font-size: 17px; line-height: 1;
            cursor: pointer; color: #6E6E6E; padding: 4px; }
.afcrop-x:hover { color: #1F1F1F; }

/* The toolbar that tells the user what is wrong with their image. */
.afcrop-issues { display: flex; flex-direction: column; gap: 1px;
                 background: #E7E7E7; border-bottom: 1px solid #E7E7E7; }
.afcrop-issue { display: flex; gap: 8px; padding: 9px 18px; font-size: 13px; }
.afcrop-issue.ok       { background: #F1F8F2; color: #1E6B33; }
.afcrop-issue.info     { background: #FFF8EC; color: #8A5A10; }
.afcrop-issue.blocking { background: #FDF1F1; color: #A62121; }

.afcrop-stage { position: relative; flex: 1; min-height: 220px;
                display: flex; align-items: center; justify-content: center;
                padding: 18px; background: #2B2B2B; overflow: hidden;
                touch-action: none; user-select: none; }
.afcrop-img { max-width: 100%; max-height: 52vh; display: block;
              -webkit-user-drag: none; user-select: none; }

/* Everything outside the frame is dimmed, so what will be kept is unmistakable. */
.afcrop-shade { position: absolute; inset: 0; background: rgba(20,20,20,.55);
                pointer-events: none; }

.afcrop-frame { position: absolute; cursor: move;
                border: 1px solid rgba(255,255,255,.95);
                box-shadow: 0 0 0 1px rgba(0,0,0,.35); }
/* Rule-of-thirds guides, drawn with gradients rather than extra elements. */
.afcrop-frame::before { content: ""; position: absolute; inset: 0; pointer-events: none;
    background:
      linear-gradient(to right,  transparent 33.33%, rgba(255,255,255,.28) 33.33%, rgba(255,255,255,.28) calc(33.33% + 1px), transparent calc(33.33% + 1px), transparent 66.66%, rgba(255,255,255,.28) 66.66%, rgba(255,255,255,.28) calc(66.66% + 1px), transparent calc(66.66% + 1px)),
      linear-gradient(to bottom, transparent 33.33%, rgba(255,255,255,.28) 33.33%, rgba(255,255,255,.28) calc(33.33% + 1px), transparent calc(33.33% + 1px), transparent 66.66%, rgba(255,255,255,.28) 66.66%, rgba(255,255,255,.28) calc(66.66% + 1px), transparent calc(66.66% + 1px)); }

.afcrop-h { position: absolute; width: 14px; height: 14px; background: #fff;
            border: 1px solid rgba(0,0,0,.35); border-radius: 2px; }
.afcrop-h.nw { left: -7px;  top: -7px;    cursor: nwse-resize; }
.afcrop-h.ne { right: -7px; top: -7px;    cursor: nesw-resize; }
.afcrop-h.sw { left: -7px;  bottom: -7px; cursor: nesw-resize; }
.afcrop-h.se { right: -7px; bottom: -7px; cursor: nwse-resize; }

/* Live output size - red the moment the crop drops below the minimum. Sits INSIDE the
   frame: below it, the badge is clipped by the stage whenever the frame reaches the
   bottom edge, which is exactly when the user most needs to read it. */
.afcrop-size { position: absolute; left: 50%; bottom: 6px; transform: translateX(-50%);
               padding: 2px 7px; border-radius: 3px; font-size: 11px; font-weight: 600;
               white-space: nowrap; background: rgba(20,20,20,.8); color: #fff; }
.afcrop-size.bad { background: #A62121; }

.afcrop-foot { display: flex; align-items: center; gap: 10px;
               padding: 12px 18px; border-top: 1px solid #E7E7E7; background: #FAFAFA; }
.afcrop-req { font-size: 12px; color: #6E6E6E; }
.afcrop-spacer { flex: 1; }
.afcrop-btn { padding: 8px 16px; border-radius: 5px; font-size: 13px; font-weight: 600;
              cursor: pointer; border: 1px solid transparent; }
.afcrop-btn.ghost   { background: #fff; border-color: #D5D5D5; color: #1F1F1F; }
.afcrop-btn.primary { background: #1F1F1F; color: #fff; }
.afcrop-btn:disabled { opacity: .45; cursor: not-allowed; }

@media (max-width: 640px) {
  .afcrop-foot { flex-wrap: wrap; }
  .afcrop-req  { flex-basis: 100%; }
}

/* ============================================================================
   Brand lockup (.afbrand)

   NOT nested under .af: the admin pages carry the same lockup and never take that
   class. Prefixed instead, like .afcrop.

   The mark is a transparent PNG; the wordmark is text. The light tone inverts the
   mark to white rather than shipping a second file, which also means a new mark
   only ever has to be dropped in once.
   ============================================================================ */
.afbrand { display: inline-flex; align-items: center; gap: 10px; flex: none;
           text-decoration: none; line-height: 1; }
.afbrand-mark { display: block; width: auto; flex: none;
                /* the calligraphy sits optically high against cap-height text */
                transform: translateY(-1px); }
.afbrand-words { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.afbrand-name { font-weight: 800; letter-spacing: .1em; white-space: nowrap; }
.afbrand-sub  { font-weight: 600; letter-spacing: .16em; text-transform: uppercase;
                white-space: nowrap; }

/* ---- sizes ---- */
.afbrand--sm .afbrand-mark { height: 26px; }
.afbrand--sm .afbrand-name { font-size: 15px; }
.afbrand--sm .afbrand-sub  { font-size: 8.5px; }

.afbrand--md .afbrand-mark { height: 34px; }
.afbrand--md .afbrand-name { font-size: 19px; }
.afbrand--md .afbrand-sub  { font-size: 9.5px; }

.afbrand--lg .afbrand-mark { height: 54px; }
.afbrand--lg .afbrand-name { font-size: 26px; }
.afbrand--lg .afbrand-sub  { font-size: 11px; }

/* ---- tones ---- */
.afbrand--brand .afbrand-name { color: var(--black, #1A1A1A); }
.afbrand--brand .afbrand-sub  { color: var(--grey-mid, #6E6E6E); }

/* Turns the red mark white for dark surfaces: brightness(0) flattens every pixel to
   black, invert(1) then lifts it to white, and the alpha channel is untouched. */
.afbrand--light .afbrand-mark { filter: brightness(0) invert(1); }
.afbrand--light .afbrand-name { color: #fff; }
.afbrand--light .afbrand-sub  { color: rgba(255, 255, 255, .45); }

/* ---- variants ---- */
.afbrand--stacked { flex-direction: column; gap: 12px; text-align: center; }
.afbrand--stacked .afbrand-words { align-items: center; }

.afbrand--markonly { gap: 0; }

/* A link version gets a gentle press response; the plain <div> version gets none. */
a.afbrand { transition: opacity var(--trans, 200ms); }
a.afbrand:hover { opacity: .78; }
a.afbrand:focus-visible { outline: 2px solid var(--red, #A6192E); outline-offset: 4px;
                          border-radius: 4px; }
a.afbrand.afbrand--light:focus-visible { outline-color: #fff; }

@media (max-width: 560px) {
    /* The sub-line is the first thing to go when space is tight - the mark and name
       still identify the store on their own. */
    .afbrand--md .afbrand-sub { display: none; }
    .afbrand--md .afbrand-mark { height: 30px; }
    .afbrand--md .afbrand-name { font-size: 17px; }
}

/* ============================================================================
   Admin grid pager (.apg)

   Prefixed and outside .af, like .afcrop and .afbrand: the admin pages never carry
   that class, and these generic-sounding names would otherwise collide with the
   page-level style blocks, which are global.
   ============================================================================ */
.apg { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
       margin-top: 14px; padding-top: 12px; border-top: 1px solid #E9E7E5;
       font-size: 13px; color: #6E6E6E; }
.apg-info { font-variant-numeric: tabular-nums; }
.apg-sp { flex: 1; }
.apg-page { font-variant-numeric: tabular-nums; }
.apg-btn {
    padding: 6px 12px; border-radius: 6px; border: 1px solid #D5D5D5;
    background: #fff; color: #1A1A1A; font-size: 13px; font-weight: 600; cursor: pointer;
}
.apg-btn:hover:not(:disabled) { border-color: #A6192E; color: #A6192E; }
.apg-btn:disabled { opacity: .45; cursor: not-allowed; }

/* "from" prefix on a card whose variants are not all the same price - the figure beside
   it is the cheapest variant, and presenting that as a flat price would misquote the rest. */
.af .fromlbl { font-size: 11.5px; font-weight: 600; color: var(--grey-mid);
               text-transform: lowercase; margin-inline-end: 3px; }

/* Checkout notice: prices that moved while the items sat in the bag. */
.af .repriced { background: #FFF8EC; border: 1px solid #EAD9AE; border-radius: 8px;
                padding: 12px 14px; margin-bottom: 14px; font-size: 13px; color: #7A5B10; }
.af .repriced p { margin: 4px 0 8px; line-height: 1.5; }
.af .repriced-line { display: flex; justify-content: space-between; gap: 12px;
                     padding: 4px 0; border-top: 1px solid rgba(122, 91, 16, .15); }
.af .repriced-line s { color: #9A8558; margin-inline-end: 6px; }
.af .repriced-line .up { color: #A6192E; }
.af .repriced-line .down { color: #2E7D32; }

/* ============================================================================
   Bag → Checkout journey

   The whole journey shares one shell: a wide content column with a summary panel
   pinned beside it. The summary is the point - previously the customer entered an
   address with no idea what was in the order or what it cost, and the only way to
   check was to leave checkout. It sticks, so it is on screen at every step.

   Everything below uses design-system tokens only (--red, --grey-*, --radius,
   --shadow-*), so this stays consistent with the rest of the storefront rather
   than being a second look bolted on.
   ============================================================================ */

.af .jshell { max-width: var(--maxw); margin: 0 auto; padding: var(--s5) 20px var(--s8); }
.af .jhead { margin-bottom: var(--s5); }
.af .jhead h1 { font-size: clamp(22px, 3vw, 30px); font-weight: 800; letter-spacing: -.01em; }
.af .jhead .jsub { font-size: 13.5px; color: var(--grey-mid); margin-top: 4px; }

/* Two columns: the work on the left, the summary pinned on the right. */
.af .jgrid { display: grid; grid-template-columns: minmax(0, 1fr) 348px; gap: var(--s5); align-items: start; }
@media (max-width: 900px) { .af .jgrid { grid-template-columns: minmax(0, 1fr); } }

.af .jmain { display: flex; flex-direction: column; min-width: 0; }

/* ---------- stepper ----------
   Three states, not one. The old version rendered every step in brand red whether
   it was done, current or still ahead, which made it decoration rather than
   progress. Done carries a tick, current is filled, ahead is a hollow outline. */
.af .stepper { display: flex; align-items: flex-start; margin-bottom: var(--s5); }
.af .stepper .st { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 7px;
                   position: relative; text-align: center; }
/* The connector is drawn behind the bubble and stops short of it on both sides. */
.af .stepper .st::before,
.af .stepper .st::after {
    content: ""; position: absolute; top: 15px; height: 2px; background: var(--grey-light);
}
.af .stepper .st::before { inset-inline-start: 0; width: calc(50% - 22px); }
.af .stepper .st::after  { inset-inline-end: 0;  width: calc(50% - 22px); }
.af .stepper .st:first-child::before,
.af .stepper .st:last-child::after { display: none; }
.af .stepper .st.done::before, .af .stepper .st.done::after,
.af .stepper .st.on::before { background: var(--red); }

.af .stepper .bub {
    width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center;
    font-size: 13px; font-weight: 700; position: relative; z-index: 1;
    background: var(--white); border: 2px solid var(--grey-light); color: var(--grey-mid);
    transition: all var(--trans);
}
.af .stepper .st.on .bub   { background: var(--red); border-color: var(--red); color: #fff;
                             box-shadow: 0 0 0 4px var(--red-tint); }
.af .stepper .st.done .bub { background: var(--red); border-color: var(--red); color: #fff; }
.af .stepper .lbl { font-size: 12px; font-weight: 600; color: var(--grey-mid); letter-spacing: .02em; }
.af .stepper .st.on .lbl { color: var(--black); }
.af .stepper .st.done .lbl { color: var(--grey); }
@media (max-width: 560px) { .af .stepper .lbl { display: none; } }

/* ---------- panels ---------- */
.af .jcard { background: #fff; border: 1px solid var(--grey-light); border-radius: 14px;
             padding: var(--s5); }
.af .jcard + .jcard { margin-top: var(--s4); }
.af .jcard h2 { font-size: 15px; font-weight: 700; letter-spacing: -.005em; margin-bottom: var(--s4);
                display: flex; align-items: center; gap: 8px; }
.af .jcard h2 .ico { color: var(--grey-mid); }

/* ---------- selectable option (address, delivery method) ---------- */
.af .opt {
    display: flex; align-items: flex-start; gap: 12px; padding: 14px 16px; cursor: pointer;
    border: 1.5px solid var(--grey-light); border-radius: 10px; margin-bottom: 10px;
    transition: border-color var(--trans), background var(--trans);
}
.af .opt:hover { border-color: #C9C4BE; }
.af .opt.on { border-color: var(--red); background: var(--red-tint); }
.af .opt input[type=radio] { margin-top: 2px; accent-color: var(--red); flex: none; }
.af .opt .obody { flex: 1; min-width: 0; }
.af .opt .otitle { font-weight: 700; font-size: 14px; }
.af .opt .ometa { font-size: 12.5px; color: var(--grey-mid); margin-top: 3px; line-height: 1.5; }
.af .opt .oprice { font-weight: 700; font-size: 14px; white-space: nowrap; }
.af .opt .odel { background: none; border: 0; color: var(--grey-mid); cursor: pointer; padding: 2px;
                 display: grid; place-items: center; border-radius: 6px; }
.af .opt .odel:hover { color: var(--red); background: rgba(166, 25, 46, .08); }

/* ---------- line items (bag page + summary) ---------- */
.af .jline { display: flex; gap: 14px; padding: 14px 0; border-bottom: 1px solid var(--grey-light); }
.af .jline:last-child { border-bottom: 0; }
.af .jthumb {
    width: 72px; height: 72px; flex: none; border-radius: 10px; overflow: hidden;
    background: var(--grey-pale); display: grid; place-items: center;
}
.af .jthumb img { width: 100%; height: 100%; object-fit: cover; }
.af .jthumb .ico { color: #CFCBC7; }
.af .jbody { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.af .jname { font-size: 14px; font-weight: 600; line-height: 1.4; }
.af .jmeta { font-size: 12.5px; color: var(--grey-mid); }
.af .jright { display: flex; flex-direction: column; align-items: flex-end; justify-content: space-between; gap: 8px; }
.af .jprice { font-weight: 700; font-size: 14.5px; white-space: nowrap; font-variant-numeric: tabular-nums; }

/* Quantity stepper - one pill rather than three loose controls. */
.af .qty { display: inline-flex; align-items: center; border: 1.5px solid var(--grey-light);
           border-radius: 999px; overflow: hidden; }
.af .qty button {
    width: 30px; height: 30px; border: 0; background: none; cursor: pointer; color: var(--grey);
    display: grid; place-items: center; transition: background var(--trans);
}
.af .qty button:hover:not(:disabled) { background: var(--grey-pale); color: var(--red); }
.af .qty button:disabled { opacity: .35; cursor: not-allowed; }
.af .qty .n { min-width: 26px; text-align: center; font-size: 13.5px; font-weight: 700;
              font-variant-numeric: tabular-nums; }

/* ---------- summary panel ---------- */
.af .jsum { position: sticky; top: 20px; background: #fff; border: 1px solid var(--grey-light);
            border-radius: 14px; overflow: hidden; }
.af .jsum-head { padding: 16px 18px; border-bottom: 1px solid var(--grey-light);
                 display: flex; align-items: center; justify-content: space-between; }
.af .jsum-head h3 { font-size: 14px; font-weight: 700; }
.af .jsum-head .n { font-size: 12.5px; color: var(--grey-mid); }
.af .jsum-items { max-height: 296px; overflow-y: auto; padding: 4px 18px; }
.af .jsum-items .jline { padding: 12px 0; }
.af .jsum-items .jthumb { width: 52px; height: 52px; border-radius: 8px; }
.af .jsum-items .jname { font-size: 13px; }
.af .jsum-rows { padding: 14px 18px; border-top: 1px solid var(--grey-light); }
.af .jrow { display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
            font-size: 13.5px; padding: 5px 0; color: var(--grey); }
.af .jrow b { font-weight: 700; color: var(--black); font-variant-numeric: tabular-nums; }
.af .jrow.free b { color: var(--success); }
.af .jrow.disc b { color: var(--red); }
.af .jrow.grand { border-top: 1px solid var(--grey-light); margin-top: 8px; padding-top: 12px;
                  font-size: 16px; font-weight: 800; color: var(--black); }
.af .jrow.grand b { font-size: 19px; }

/* ---------- reassurance strip ---------- */
.af .jtrust { display: flex; flex-direction: column; gap: 9px; padding: 14px 18px;
              border-top: 1px solid var(--grey-light); background: var(--grey-pale);
              list-style: none; margin: 0; }
.af .jtrust li { display: flex; align-items: center; gap: 9px; font-size: 12.5px; color: var(--grey); }
.af .jtrust .ico { color: var(--grey-mid); flex: none; }

/* ---------- callouts ---------- */
.af .jnote { display: flex; align-items: flex-start; gap: 9px; font-size: 13px; line-height: 1.5;
             padding: 12px 14px; border-radius: 10px; }
.af .jnote .ico { flex: none; margin-top: 1px; }
.af .jnote.points { background: var(--warning-tint); color: #7A5B10; }
.af .jnote.ok { background: var(--success-tint); color: var(--success); }
.af .jnote.warn { background: #FFF8EC; color: #8A5A10; }
.af .jnote.bad { background: var(--red-tint); color: var(--red); }

/* ---------- actions ---------- */
.af .jactions { display: flex; align-items: center; justify-content: space-between; gap: 12px;
                margin-top: var(--s5); }
.af .jbtn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    padding: 13px 22px; border-radius: 10px; font-size: 14.5px; font-weight: 700;
    border: 1.5px solid transparent; cursor: pointer; text-decoration: none;
    transition: background var(--trans), border-color var(--trans), transform var(--trans);
}
.af .jbtn.primary { background: var(--red); color: #fff; }
.af .jbtn.primary:hover:not(:disabled) { background: var(--red-dark); }
.af .jbtn.ghost { background: #fff; border-color: var(--grey-light); color: var(--grey); }
.af .jbtn.ghost:hover { border-color: var(--grey-mid); color: var(--black); }
.af .jbtn.block { width: 100%; }
.af .jbtn:disabled { opacity: .45; cursor: not-allowed; }
.af .jbtn:active:not(:disabled) { transform: translateY(1px); }
.af .jlink { background: none; border: 0; padding: 0; cursor: pointer; font-size: 13.5px;
             color: var(--grey-mid); text-decoration: none; display: inline-flex;
             align-items: center; gap: 5px; }
.af .jlink:hover { color: var(--red); }

/* ---------- empty / loading / success states ---------- */
.af .jstate { text-align: center; padding: 72px 20px; }
.af .jstate .art { width: 64px; height: 64px; margin: 0 auto 18px; border-radius: 50%;
                   display: grid; place-items: center; background: var(--grey-pale); color: var(--grey-mid); }
.af .jstate .art.good { background: var(--success-tint); color: var(--success); }
.af .jstate h3 { font-size: 18px; font-weight: 700; margin-bottom: 6px; }
.af .jstate p { font-size: 13.5px; color: var(--grey-mid); margin-bottom: 20px; }

@media (prefers-reduced-motion: reduce) {
    .af .jbtn, .af .stepper .bub, .af .opt, .af .qty button { transition: none; }
}
/* ---------------------------------------------------------------------------
   Savings strip + Apply Coupons popup
   ---------------------------------------------------------------------------
   Coupons and points sit inside the order summary, immediately above the rows
   they change, so the customer never has to leave the total to improve it.
   Each entry has two states - an invitation (.jsave-btn) and a confirmation
   (.jsave-on) - and they occupy the same footprint so applying one does not
   make the panel jump.                                                       */
.af .jsave { padding: 12px 18px; border-top: 1px solid var(--grey-light);
             display: flex; flex-direction: column; gap: 8px; }

.af .jsave-btn, .af .jsave-on {
    display: flex; align-items: center; gap: 10px; width: 100%; text-align: start;
    padding: 10px 12px; border-radius: 10px; border: 1.5px dashed var(--grey-light);
    background: #fff; font: inherit; color: inherit;
}
.af .jsave-btn { cursor: pointer; transition: border-color .16s, background .16s; }
.af .jsave-btn:hover { border-color: var(--red); background: var(--red-tint); }
.af .jsave-on { border-style: solid; border-color: var(--success);
                background: var(--success-tint); }

.af .jsave .ic { flex: none; display: flex; color: var(--red); }
.af .jsave-on .ic { color: var(--success); }
.af .jsave .tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.af .jsave .tx b { font-size: 13px; font-weight: 700; }
.af .jsave .tx em { font-size: 11.5px; font-style: normal; color: var(--grey-mid); }
.af .jsave .tx em.hot { color: var(--red); font-weight: 600; }
.af .jsave-on .tx em { color: var(--success); }
.af .jsave .go { flex: none; color: var(--grey-mid); display: flex; }
.af .jsave-btn:hover .go { color: var(--red); }

/* A quiet aside under the delivery line - not a total, so not a .jrow. */
.af .jhint { font-size: 11.5px; color: var(--grey-mid); padding: 0 0 8px;
             margin-top: -4px; }

/* --- the popup ----------------------------------------------------------- */
.af .jmodal { position: fixed; inset: 0; z-index: 120; display: flex;
              align-items: center; justify-content: center; padding: 20px;
              background: rgba(20, 18, 17, .55); backdrop-filter: blur(3px);
              animation: jfade .18s ease; }
.af .jmodal-card { width: 100%; max-width: 440px; max-height: 86vh; display: flex;
                   flex-direction: column; background: #fff; border-radius: 16px;
                   overflow: hidden; box-shadow: 0 24px 60px rgba(0, 0, 0, .28);
                   animation: jrise .2s cubic-bezier(.2, .8, .3, 1); }
.af .jmodal-head { display: flex; align-items: center; justify-content: space-between;
                   gap: 12px; padding: 16px 18px; border-bottom: 1px solid var(--grey-light); }
.af .jmodal-head h3 { display: flex; align-items: center; gap: 9px;
                      font-size: 15px; font-weight: 700; }
.af .jmodal-x { background: none; border: 0; cursor: pointer; padding: 4px; display: flex;
                border-radius: 6px; color: var(--grey-mid); }
.af .jmodal-x:hover { color: var(--red); background: var(--red-tint); }
.af .jmodal-body { padding: 16px 18px 20px; overflow-y: auto; }

@keyframes jfade { from { opacity: 0; } }
@keyframes jrise { from { opacity: 0; transform: translateY(14px) scale(.98); } }

/* --- one offer, drawn as a ticket ---------------------------------------- */
.af .cpns { display: flex; flex-direction: column; gap: 10px; margin-top: 16px; }
.af .cpn { display: flex; align-items: stretch; gap: 12px; padding: 12px;
           border: 1.5px solid var(--grey-light); border-radius: 12px; background: #fff; }
.af .cpn.off { background: var(--grey-pale); border-style: dashed; }

/* The stub is the torn-off half of a paper coupon: the perforation is the dashed
   inline-end border, and the two notches are what a punch would leave behind. */
.af .cpn-stub { position: relative; flex: none; width: 92px; padding-inline-end: 12px;
                border-inline-end: 1.5px dashed var(--grey-light);
                display: flex; flex-direction: column; justify-content: center; gap: 3px; }
.af .cpn-stub::before, .af .cpn-stub::after {
    content: ""; position: absolute; inset-inline-end: -6px; width: 10px; height: 10px;
    border-radius: 50%; background: #fff; border: 1.5px solid var(--grey-light);
}
.af .cpn-stub::before { top: -7px; }
.af .cpn-stub::after { bottom: -7px; }
.af .cpn-stub .v { font-size: 15px; font-weight: 800; color: var(--red); line-height: 1.2; }
.af .cpn.off .cpn-stub .v { color: var(--grey-mid); }
.af .cpn-stub .c { font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase;
                   color: var(--grey-mid); font-weight: 700; }

.af .cpn-body { flex: 1; min-width: 0; display: flex; flex-direction: column;
                justify-content: center; gap: 3px; }
.af .cpn-name { font-size: 13px; font-weight: 700; }
.af .cpn-meta { font-size: 11.5px; color: var(--grey-mid); }
.af .cpn-meta.win { color: var(--success); font-weight: 600; }
.af .cpn-act { flex: none; display: flex; align-items: center; }
.af .jbtn.sm { padding: 7px 14px; font-size: 12.5px; }

@media (max-width: 520px) {
    .af .cpn-stub { width: 76px; }
}

@media (prefers-reduced-motion: reduce) {
    .af .jmodal, .af .jmodal-card { animation: none; }
    .af .jsave-btn { transition: none; }
}
/* ---------------------------------------------------------------------------
   Legal pages (Privacy Policy, Terms & Conditions)
   ---------------------------------------------------------------------------
   A prose column, not a layout. These pages exist to be read start to finish -
   so the measure is capped near 70 characters, headings are quiet enough to
   scan without shouting, and nothing competes with the text.

   Scoped .af.legal (both classes on one element) rather than .af .legal, the
   same way .af.acct is, so .wrap here cannot reach any other page's .wrap.   */
.af.legal .wrap { max-width: 820px; margin: 0 auto; padding: 24px 20px 64px; }
.af.legal .crumb { font-size: 13px; color: var(--grey-mid); margin-bottom: 18px; }
.af.legal .crumb a { color: var(--grey-mid); text-decoration: none; }
.af.legal .crumb a:hover { color: var(--red); }

.af.legal h1 { font-size: 30px; font-weight: 800; letter-spacing: -.01em; line-height: 1.2; }
.af.legal .lead { font-size: 13px; color: var(--grey-mid); margin-top: 8px;
                  padding-bottom: 20px; border-bottom: 1px solid var(--grey-light); }

.af.legal section { margin-top: 30px; }
.af.legal h2 { font-size: 16px; font-weight: 700; color: var(--black); margin-bottom: 10px; }
.af.legal p { font-size: 14.5px; line-height: 1.75; color: var(--grey); max-width: 70ch; }
.af.legal p + p { margin-top: 12px; }
.af.legal a { color: var(--red); }

.af.legal ul { margin: 12px 0 14px; padding: 0; list-style: none; max-width: 70ch; }
.af.legal li { position: relative; font-size: 14.5px; line-height: 1.7; color: var(--grey);
               padding-inline-start: 18px; padding-block: 3px; }
/* A marker drawn rather than a list bullet, so it stays on the correct side in Arabic. */
.af.legal li::before { content: ""; position: absolute; inset-inline-start: 2px; top: 12px;
                       width: 5px; height: 5px; border-radius: 50%; background: var(--red); }

/* The one passage the supplied copy singles out. Bordered rather than badged - the
   original carried a warning emoji, which this project does not use as iconography. */
.af.legal .callout { margin-top: 30px; padding: 18px 20px; border-radius: 12px;
                     background: var(--warning-tint); border: 1px solid #EBD9A8;
                     border-inline-start: 4px solid var(--warning); }
.af.legal .callout h2 { color: #7A5B10; }
.af.legal .callout p { color: #6B5210; }

.af.legal .legal-foot { margin-top: 36px; padding-top: 18px;
                        border-top: 1px solid var(--grey-light); }
.af.legal .legal-foot p { font-size: 13.5px; color: var(--grey-mid); }

@media (max-width: 620px) {
    .af.legal h1 { font-size: 24px; }
}

/* Per-line stock hints in the bag. Sits beside the quantity stepper, because that is
   the control the number constrains - a message anywhere else would be about the
   product rather than about the choice being made. */
.af .stk { display: inline-flex; align-items: center; gap: 5px; margin-inline-start: 10px;
           font-size: 12px; font-weight: 600; vertical-align: middle; }
.af .stk.low { color: var(--grey-mid); font-weight: 500; }
.af .stk.out { color: var(--red); }
/* The over-stocked one is a button: it says what is wrong AND fixes it in one click. */
.af .stk.fix { color: var(--red); background: var(--red-tint); border: 0; cursor: pointer;
               padding: 4px 9px; border-radius: 999px; font-family: inherit; }
.af .stk.fix:hover { background: var(--red); color: #fff; }

/* A capped stepper has to look capped, or it reads as broken. */
.af .qty button:disabled, .af .cqty .stepbtn:disabled { opacity: .35; cursor: not-allowed; }
