/*
 * seller.id storefront — Template A "Kanvas" (minimalis editorial).
 * Visual direction locked: docs/design/visual-direction.md §2A + §3.
 *
 * Galeri, bukan katalog. Latar putih, tinta #111114, TANPA warna aksen —
 * tombol hitam solid, badge hitam/putih. Kemewahan datang dari ruang:
 * hero full-bleed, grid lega, kartu tanpa border, tipografi Fraunces yang
 * diam. Foto produk yang jualan, kromnya cuma nemenin.
 *
 * ZERO JavaScript: sticky, hover-zoom, dan accordion semuanya CSS/HTML asli
 * (position: sticky, transform, <details>). Semua gerak dikurung di dalam
 * prefers-reduced-motion: no-preference.
 *
 * Served as a plain file from public/css (byte-identical copy of this
 * source) — no build step. Fonts bundled locally in public/fonts (from
 * @fontsource, latin subset), NEVER a runtime CDN.
 */

/* ---------------------------------------------------------------- fonts */

@font-face {
    font-family: 'Fraunces';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('/fonts/fraunces-latin-600-normal.woff2') format('woff2');
}

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

@font-face {
    font-family: 'Public Sans';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/fonts/public-sans-latin-400-normal.woff2') format('woff2');
}

@font-face {
    font-family: 'Public Sans';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('/fonts/public-sans-latin-500-normal.woff2') format('woff2');
}

/* --------------------------------------------------------------- tokens */

:root {
    --bg: #FFFFFF;
    --ink: #111114;
    --ink-hover: #2C2C33;
    --muted: #6B6E76;
    --hairline: #E6E7E9;
    --wash: #F4F4F5;          /* dasar placeholder & media kosong */
    --danger: #B3261E;        /* HANYA pesan galat form (semantik, bukan aksen) */
    --focus: #2563A8;         /* data-blue, aturan lintas-surface §3 */
    --display: 'Fraunces', Georgia, serif;
    --body: 'Public Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
    --header-h: 60px;
    --gutter: 20px;
    --maxw: 1280px;
}

/* ----------------------------------------------------------------- base */

*,
*::before,
*::after {
    box-sizing: border-box;
}

body {
    margin: 0;
    background: var(--bg);
    color: var(--ink);
    font-family: var(--body);
    font-size: 1rem;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

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

a {
    color: inherit;
}

:focus-visible {
    outline: 2px solid var(--focus);
    outline-offset: 2px;
}

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    background: var(--ink);
    color: #FFFFFF;
    padding: 10px 16px;
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
}

.skip-link:focus {
    left: 8px;
    top: 8px;
}

/* Rupiah storefront: Public Sans tabular (mono khusus dashboard, §3). */
.price-amount {
    font-family: var(--body);
    font-variant-numeric: tabular-nums;
}

/* Visually hidden, still read aloud — the gallery's thumbnail links carry
   their meaning here ("Lihat foto 2 dari 4"), since the image itself is
   decorative. */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.sf-container {
    width: 100%;
    max-width: var(--maxw);
    margin-inline: auto;
    padding-inline: var(--gutter);
}

.sf-container.sf-narrow {
    max-width: 860px;
}

.sf-eyebrow {
    margin: 0;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--muted);
}

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

.sf-announce {
    background: var(--ink);
    color: #FFFFFF;
}

.sf-announce-text {
    margin: 0 auto;
    max-width: var(--maxw);
    padding: 9px var(--gutter);
    text-align: center;
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
}

/* Sticky bar only — the announcement strip above scrolls away, so no
   offset ever has to be measured or guessed. */
.sf-header {
    position: sticky;
    top: 0;
    z-index: 20;
    background: rgba(255, 255, 255, 0.94);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--hairline);
}

.sf-header-inner {
    max-width: var(--maxw);
    margin-inline: auto;
    padding-inline: var(--gutter);
    min-height: var(--header-h);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}

.sf-brand {
    text-decoration: none;
    min-width: 0;
}

.sf-brand-name {
    display: block;
    font-family: var(--display);
    font-weight: 600;
    font-size: 1.2rem;
    letter-spacing: -0.02em;
    line-height: 1.1;
}

.store-logo {
    height: 34px;
    width: auto;
}

.sf-nav {
    display: flex;
    align-items: center;
    gap: 20px;
}

.sf-nav-link,
.sf-cart-link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    text-decoration: none;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--muted);
}

.sf-nav-link:hover,
.sf-cart-link:hover {
    color: var(--ink);
}

.sf-cart-link {
    color: var(--ink);
}

.sf-cart-count {
    min-width: 20px;
    height: 20px;
    padding-inline: 6px;
    display: inline-grid;
    place-items: center;
    border-radius: 999px;
    background: var(--ink);
    color: #FFFFFF;
    font-size: 0.66rem;
    letter-spacing: 0;
    font-variant-numeric: tabular-nums;
}

.sf-cart-count--kosong {
    background: transparent;
    color: var(--muted);
    border: 1px solid var(--hairline);
}

/* Hide the small-screen nav label, keep the count — the link keeps its
   aria-label either way. */
@media (max-width: 479px) {
    .sf-nav-link {
        display: none;
    }
}

/* --------------------------------------------------- kategori + cari */

/* Quiet text links on a hairline shelf under the sticky bar. Kanvas has no
   accent colour, so the active one is marked by an underline and full-ink
   weight, never by a filled chip. Scrolls sideways on a narrow phone rather
   than wrapping into a second row that would push the grid down. */
.sf-kategori {
    border-bottom: 1px solid var(--hairline);
    background: rgba(255, 255, 255, 0.94);
}

.sf-kategori-inner {
    max-width: var(--maxw);
    margin-inline: auto;
    padding: 10px var(--gutter);
    display: flex;
    gap: 22px;
    overflow-x: auto;
    scrollbar-width: none;
}

.sf-kategori-inner::-webkit-scrollbar {
    display: none;
}

.sf-kategori-link {
    flex: 0 0 auto;
    text-decoration: none;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--muted);
    white-space: nowrap;
}

.sf-kategori-link:hover {
    color: var(--ink);
}

.sf-kategori-link--aktif {
    color: var(--ink);
    text-decoration: underline;
    text-underline-offset: 5px;
    text-decoration-thickness: 1px;
}

.sf-search {
    display: flex;
    align-items: center;
    gap: 6px;
}

.sf-search-input {
    width: 148px;
    height: 34px;
    padding-inline: 10px;
    border: 1px solid var(--hairline);
    border-radius: 0;
    background: #FFFFFF;
    color: var(--ink);
    font-family: var(--body);
    font-size: 0.82rem;
}

.sf-search-input:focus-visible {
    outline: 2px solid var(--focus);
    outline-offset: 1px;
}

.sf-search-btn {
    height: 34px;
    padding-inline: 12px;
    border: 1px solid var(--ink);
    border-radius: 0;
    background: transparent;
    color: var(--ink);
    font-family: var(--body);
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    cursor: pointer;
}

.sf-search-btn:hover {
    background: var(--ink);
    color: #FFFFFF;
}

/* Sorting is a row of links, so it is bookmarkable and needs no JS. */
.sf-urut {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 8px 18px;
    margin-bottom: 22px;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
}

.sf-urut-label {
    color: var(--muted);
}

.sf-urut-link {
    text-decoration: none;
    color: var(--muted);
}

.sf-urut-link:hover {
    color: var(--ink);
}

.sf-urut-link--aktif {
    color: var(--ink);
    text-decoration: underline;
    text-underline-offset: 4px;
}

/* Narrow phones: the search field would squeeze the brand out of the bar. */
@media (max-width: 599px) {
    .sf-search-input {
        width: 110px;
    }

    .sf-search-btn {
        display: none;
    }
}

/* ----------------------------------------------------------------- hero */

/* Sized to its content, not to the viewport: a fixed 68vh band pushed the
   first product entirely below the fold on a phone. Full-bleed wash + a
   hairline close, so it still reads as a hero, not as a stray heading. */
.hero--kanvas {
    display: grid;
    place-items: center;
    min-height: 340px;
    padding-block: clamp(48px, 9vw, 104px);
    border-bottom: 1px solid var(--hairline);
    background: linear-gradient(158deg, #FAFAFB 0%, #F1F1F3 55%, #E8E8EC 100%);
}

.hero-overlay {
    max-width: 720px;
    padding-inline: var(--gutter);
    text-align: center;
    color: var(--ink);
}

.hero-title {
    margin: 0.24em 0 0.16em;
    font-family: var(--display);
    font-weight: 600;
    font-size: clamp(2.4rem, 7vw, 4.4rem);
    line-height: 1.02;
    letter-spacing: -0.035em;
}

.hero-sub {
    margin: 0 0 26px;
    font-size: clamp(0.95rem, 1.6vw, 1.05rem);
}

/* -------------------------------------------------------------- buttons */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 46px;
    padding-inline: 26px;
    border: 1px solid transparent;
    border-radius: 0;
    font-family: var(--body);
    font-size: 0.78rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    text-decoration: none;
    cursor: pointer;
}

.btn-primary {
    background: var(--ink);
    color: #FFFFFF;
}

.btn-primary:hover {
    background: var(--ink-hover);
}

.btn-primary:active {
    background: #000000;
}

.btn-block {
    width: 100%;
}

.btn:disabled,
.btn[disabled] {
    opacity: 0.4;
    cursor: not-allowed;
}

.btn-remove {
    min-height: 34px;
    padding-inline: 14px;
    background: transparent;
    border-color: var(--hairline);
    color: var(--muted);
    font-size: 0.68rem;
}

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

.sf-textlink {
    display: inline-block;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--muted);
    text-align: center;
}

.sf-textlink:hover {
    color: var(--ink);
}

/* ------------------------------------------------------------- sections */

.sf-main {
    display: block;
}

.sf-section {
    padding-block: clamp(36px, 6vw, 76px);
    /* Anchor jumps (#konten, #produk) must clear the sticky bar. */
    scroll-margin-top: calc(var(--header-h) + 8px);
}

.sf-section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    padding-bottom: 14px;
    margin-bottom: clamp(20px, 3vw, 34px);
    border-bottom: 1px solid var(--hairline);
}

.sf-section-title {
    margin: 0;
    font-family: var(--display);
    font-weight: 600;
    font-size: clamp(1.5rem, 3vw, 2.1rem);
    line-height: 1.1;
    letter-spacing: -0.025em;
}

.sf-section-meta {
    margin: 0;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--muted);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.sf-empty {
    margin: 0;
    padding-block: 28px;
    color: var(--muted);
}

.sf-notice {
    margin: 0 0 20px;
    padding: 12px 14px;
    border: 1px solid var(--hairline);
    font-size: 0.85rem;
}

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

.product-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px 12px;
}

@media (min-width: 720px) {
    .product-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 24px 20px;
    }
}

@media (min-width: 1080px) {
    .product-grid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
        gap: 44px 32px;
    }
}

/* ----------------------------------------------------------------- card */

.product-card {
    min-width: 0;
}

.product-card-media {
    position: relative;
    aspect-ratio: 4 / 5;
    overflow: hidden;
    background: var(--wash);
}

.product-media {
    display: block;
    width: 100%;
    height: 100%;
    /* The card's media is an <a>: without this the placeholder initial
       inherits the link underline and renders a bar across the block. */
    text-decoration: none;
}

.product-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* No-photo state is designed, not apologetic — and it has to survive a grid
   where EVERY card is photoless. Three deliberate signals: a ruled hairline
   field (the editorial register Kanvas already speaks), the product initial
   at readable weight, and the store wordmark. */
.product-media-placeholder {
    display: grid;
    align-content: center;
    justify-items: center;
    gap: 10px;
    width: 100%;
    height: 100%;
    padding: 14px;
    background:
        repeating-linear-gradient(
            180deg,
            rgba(17, 17, 20, 0.05) 0,
            rgba(17, 17, 20, 0.05) 1px,
            transparent 1px,
            transparent 15px
        ),
        linear-gradient(150deg, #FAFAFA 0%, #F0F0F2 55%, #E7E7EB 100%);
}

.ph-inisial {
    font-family: var(--display);
    font-weight: 600;
    font-size: clamp(2.4rem, 7vw, 4rem);
    line-height: 1;
    color: rgba(17, 17, 20, 0.34);
}

.ph-wordmark {
    max-width: 100%;
    overflow: hidden;
    font-size: 0.6rem;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    white-space: nowrap;
    text-overflow: ellipsis;
    color: rgba(17, 17, 20, 0.42);
}

.product-card-body {
    display: block;
    padding-top: 12px;
    text-decoration: none;
    color: inherit;
}

.product-name {
    display: block;
    font-size: 0.92rem;
    line-height: 1.35;
    /* Two lines reserved so prices sit on one baseline across the row. */
    min-height: 2.7em;
    min-height: 2lh;
}

.product-card:hover .product-name {
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 1px;
}

.product-price {
    display: block;
    margin-top: 3px;
    font-size: 0.88rem;
    color: var(--muted);
}

.badge {
    position: absolute;
    top: 10px;
    left: 10px;
    z-index: 2;
    padding: 5px 9px;
    background: var(--ink);
    color: #FFFFFF;
    font-size: 0.6rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------- pager */

.sf-pager {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 10px 20px;
    margin-top: clamp(28px, 4vw, 48px);
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
}

.sf-pager-link {
    color: var(--ink);
    text-decoration: none;
}

.sf-pager-link:hover {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.sf-pager-link--disabled {
    color: #C4C5C9;
}

.sf-pager-status {
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

/* -------------------------------------------------------- product page */

.sf-breadcrumb {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 24px;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--muted);
}

.sf-breadcrumb a {
    text-decoration: none;
}

.sf-breadcrumb a:hover {
    color: var(--ink);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.sf-breadcrumb-current {
    color: var(--ink);
}

.product-detail {
    display: grid;
    gap: 28px;
}

.product-media--detail {
    aspect-ratio: 4 / 5;
    overflow: hidden;
    background: var(--wash);
}

/* --------------------------------------------------------------- galeri */

/* A scroll-snap strip plus a row of anchor links. No JS: following a
   thumbnail link scrolls the strip natively, and scroll-behavior makes it
   glide — only for visitors who did not ask for less motion. */
.galeri-strip {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    aspect-ratio: 4 / 5;
    background: var(--wash);
}

.galeri-strip::-webkit-scrollbar {
    display: none;
}

.galeri-slide {
    flex: 0 0 100%;
    margin: 0;
    scroll-snap-align: start;
    height: 100%;
}

.galeri-slide img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.galeri-thumbs {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 8px 0 0;
    padding: 0;
    list-style: none;
}

.galeri-thumb {
    display: block;
    width: 62px;
    aspect-ratio: 4 / 5;
    overflow: hidden;
    border: 1px solid var(--hairline);
    background: var(--wash);
}

.galeri-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

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

.galeri-thumb:focus-visible {
    outline: 2px solid var(--focus);
    outline-offset: 2px;
}

@media (min-width: 900px) {
    .product-detail {
        grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
        gap: clamp(32px, 5vw, 72px);
        align-items: start;
    }

    .product-detail-media {
        position: sticky;
        top: calc(var(--header-h) + 24px);
    }
}

.product-detail-name {
    margin: 0 0 10px;
    font-family: var(--display);
    font-weight: 600;
    font-size: clamp(1.7rem, 3.4vw, 2.5rem);
    line-height: 1.08;
    letter-spacing: -0.03em;
}

.product-detail-price {
    margin: 0 0 8px;
    font-size: 1.25rem;
}

.stock-line {
    margin: 0 0 26px;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.stock-line--menipis,
.stock-line--habis {
    color: var(--ink);
}

/* Full width while the page is one column (it sits under a full-width
   photo); capped only once the info column has its own width. */
.cart-add-form {
    display: grid;
    gap: 16px;
    margin-bottom: 34px;
}

@media (min-width: 900px) {
    .cart-add-form {
        max-width: 420px;
    }
}

.qty-field {
    display: grid;
    gap: 6px;
}

.qty-label {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--muted);
}

.qty-input {
    width: 96px;
    height: 46px;
    padding-inline: 12px;
    border: 1px solid var(--hairline);
    border-radius: 0;
    background: #FFFFFF;
    color: var(--ink);
    font: inherit;
    font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------- varian */

/* Real radios, no JS: the label IS the hit target and the input carries the
   state, so keyboard and screen readers get the native behaviour for free.
   Kanvas keeps them as ruled rows — hairline top, hairline between, nothing
   filled — so a size list reads like the rest of the editorial column. */
.varian-group {
    margin: 0;
    padding: 0;
    border: 0;
    border-top: 1px solid var(--hairline);
}

.varian-group legend {
    padding: 0;
    margin-bottom: 10px;
}

.varian-option {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 2px;
    border-bottom: 1px solid var(--hairline);
    cursor: pointer;
}

.varian-radio {
    accent-color: var(--ink);
    width: 17px;
    height: 17px;
    flex: 0 0 auto;
}

.varian-radio:focus-visible {
    outline: 2px solid var(--focus);
    outline-offset: 2px;
}

.varian-text {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 4px 10px;
    flex: 1 1 auto;
    min-width: 0;
}

.varian-label {
    font-size: 0.92rem;
}

/* Habis/Sisa: small-caps status next to the option, never a colour-only
   signal — the disabled input already carries the machine-readable part. */
.varian-habis,
.varian-sisa {
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.varian-habis {
    color: var(--ink);
    border: 1px solid var(--hairline);
    padding: 2px 6px;
}

.varian-harga {
    font-size: 0.88rem;
    white-space: nowrap;
}

/* The whole row goes quiet when the option cannot be bought. */
.varian-option--habis {
    cursor: not-allowed;
}

.varian-option--habis .varian-label,
.varian-option--habis .varian-harga {
    color: var(--muted);
    text-decoration: line-through;
    text-decoration-thickness: 1px;
}

/* "Mulai Rp …" — the price prefix on a product whose variants diverge. */
.price-prefix {
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--muted);
    margin-right: 4px;
}

.product-details {
    border-top: 1px solid var(--hairline);
    max-width: 60ch;
}

.product-details details {
    border-bottom: 1px solid var(--hairline);
}

.product-details summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 0;
    cursor: pointer;
    list-style: none;
    font-size: 0.76rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
}

.product-details summary::-webkit-details-marker {
    display: none;
}

.product-details summary::after {
    content: '+';
    font-size: 1.1rem;
    line-height: 1;
    color: var(--muted);
}

.product-details details[open] summary::after {
    content: '\2013';
}

.product-details p {
    margin: 0 0 16px;
    font-size: 0.9rem;
    color: var(--muted);
}

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

.cart-list {
    list-style: none;
    margin: 0;
    padding: 0;
    border-top: 1px solid var(--hairline);
}

.cart-item {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px 16px;
    padding: 16px 0;
    border-bottom: 1px solid var(--hairline);
}

.cart-item-media {
    flex: 0 0 64px;
    width: 64px;
    height: 80px;
    overflow: hidden;
    background: var(--wash);
}

.cart-item-media .product-media-placeholder {
    padding: 6px;
    background-size: auto, auto; /* keep the wash, drop the ruled field */
    background-image: linear-gradient(150deg, #FAFAFA 0%, #F0F0F2 55%, #E7E7EB 100%);
}

.cart-item-media .ph-inisial {
    font-size: 1.5rem;
}

.cart-item-media .ph-wordmark {
    display: none;
}

.cart-item-info {
    flex: 1 1 200px;
    min-width: 0;
}

.cart-item-name {
    font-size: 0.95rem;
    text-decoration: none;
}

.cart-item-name:hover {
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* Varian pada baris keranjang: sub-baris kecil di bawah nama, bukan bagian
   dari nama itu sendiri — nama tetap tautan ke produknya. */
.cart-item-varian {
    margin: 2px 0 0;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--muted);
}

.cart-item-qty {
    margin: 3px 0 0;
    font-size: 0.8rem;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.cart-item-subtotal {
    margin: 0 0 0 auto;
    font-size: 0.95rem;
}

.cart-item-remove {
    flex: 0 0 auto;
}

.cart-foot {
    display: grid;
    gap: 12px;
    max-width: 420px;
    margin: 30px 0 0 auto;
}

.cart-total {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--hairline);
}

.cart-total-label {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--muted);
}

.cart-total-amount {
    font-size: 1.3rem;
    font-weight: 500;
}

.cart-note {
    margin: 0;
    font-size: 0.78rem;
    color: var(--muted);
}

/* ------------------------------------------------------------- checkout */

.checkout-layout {
    display: grid;
    gap: 34px;
}

@media (min-width: 900px) {
    .checkout-layout {
        grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
        gap: clamp(32px, 5vw, 64px);
        align-items: start;
    }

    .checkout-summary {
        position: sticky;
        top: calc(var(--header-h) + 24px);
    }
}

.checkout-heading {
    margin: 0 0 18px;
    font-family: var(--display);
    font-weight: 600;
    font-size: 1.15rem;
    letter-spacing: -0.015em;
}

.checkout-summary {
    border: 1px solid var(--hairline);
    padding: 22px;
}

.checkout-items {
    list-style: none;
    margin: 0 0 14px;
    padding: 0;
    display: grid;
    gap: 14px;
}

.checkout-item {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 2px 12px;
}

.checkout-item-name {
    grid-column: 1;
    font-size: 0.92rem;
}

.checkout-item-varian {
    display: block;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--muted);
}

.checkout-item-qty {
    grid-column: 1;
    font-size: 0.78rem;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.checkout-item-subtotal {
    grid-column: 2;
    grid-row: 1 / span 2;
    align-self: center;
    font-size: 0.92rem;
}

.checkout-summary .cart-total {
    border-bottom: 0;
    border-top: 1px solid var(--hairline);
    padding: 12px 0 0;
}

.form-field {
    display: grid;
    gap: 6px;
    margin-bottom: 18px;
}

.form-label {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--muted);
}

/* Kalimat bantuan di bawah input (kenapa kami minta datanya). */
.form-help {
    margin: 0;
    font-size: 0.8rem;
    color: var(--muted);
}

.form-input {
    width: 100%;
    padding: 12px;
    border: 1px solid var(--hairline);
    border-radius: 0;
    background: #FFFFFF;
    color: var(--ink);
    font: inherit;
}

.form-input:hover {
    border-color: #CFD0D3;
}

.form-input--area {
    resize: vertical;
}

/* ------------------------------------------------------ wilayah (alamat)
 *
 * Dropdown bertingkat tanpa JS: tombol "Tampilkan pilihan berikutnya" itu
 * submit beneran ke route checkout dengan aksi=wilayah. Blok ini cuma
 * ngiket ketiga select + tombolnya jadi satu unit visual biar kebaca
 * sebagai satu langkah, bukan tiga kolom acak.
 */
.wilayah-blok {
    margin-bottom: 18px;
    padding: 14px 14px 4px;
    border: 1px solid var(--hairline);
}

.wilayah-lanjut {
    margin-bottom: 8px;
}

.wilayah-bantuan {
    margin: 0 0 14px;
}

.form-input--pendek {
    max-width: 10ch;
}

.form-error {
    margin: 2px 0 0;
    color: var(--danger);
    font-size: 0.8rem;
}

.form-error--block {
    margin: 0 0 18px;
    padding: 10px 12px;
    border-left: 2px solid var(--danger);
    background: #FDF3F2;
}

/* ------------------------------------------------- pengiriman (Kanvas)
 *
 * Diam, sesuai §2A: garis rambut, tanpa warna aksen, yang kepilih ditandai
 * garis tinta 1px — bukan blok warna. Radio asli tetap ada (fokus keyboard,
 * required native), cuma dikecilin.
 */

.ship-group {
    margin: 0 0 22px;
    padding: 0;
    border: 0;
}

.ship-group > .checkout-heading {
    padding: 0;
    margin-bottom: 14px;
}

.ship-option {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 12px;
    padding: 14px 14px 14px 12px;
    border: 1px solid var(--hairline);
    margin-bottom: -1px;  /* garis antar opsi nyatu, bukan dobel */
    cursor: pointer;
}

.ship-option:hover {
    background: var(--wash);
}

.ship-option:has(.ship-radio:checked) {
    border-color: var(--ink);
    position: relative;
    z-index: 1;
}

.ship-option:has(.ship-radio:focus-visible) {
    outline: 2px solid var(--focus);
    outline-offset: 2px;
}

.ship-radio {
    width: 15px;
    height: 15px;
    accent-color: var(--ink);
    margin: 0;
}

.ship-text {
    display: grid;
    gap: 2px;
    min-width: 0;
}

.ship-name {
    font-size: 0.92rem;
}

.ship-eta {
    font-size: 0.78rem;
    color: var(--muted);
}

.ship-cost {
    font-size: 0.92rem;
    white-space: nowrap;
}

/* Baris ringkasan: label kiri, angka kanan — sekeluarga sama .cart-total. */
.cart-line {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    padding: 8px 0;
    border-top: 1px solid var(--hairline);
}

.cart-line-label {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--muted);
}

.cart-line-amount {
    font-size: 0.92rem;
}

/* ------------------------------------------------------ voucher (Kanvas)
 *
 * Diam, §2A: nggak ada kotak berwarna, nggak ada "HEMAT!!". Cuma satu label
 * kecil letterspaced, satu input garis rambut, satu tombol garis. Kode yang
 * kepakai ditulis pakai display face — itu satu-satunya penekanan.
 */

.voucher-blok {
    padding: 14px 0 2px;
    border-top: 1px solid var(--hairline);
}

.voucher-baris {
    display: flex;
    gap: 8px;
    margin-top: 6px;
}

.voucher-input {
    flex: 1 1 auto;
    min-width: 0;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.voucher-pakai {
    flex: 0 0 auto;
    white-space: nowrap;
}

.voucher-terpakai {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}

.voucher-terpakai-teks {
    margin: 0;
    display: flex;
    align-items: baseline;
    gap: 8px;
}

.voucher-kode {
    font-family: var(--display);
    font-weight: 600;
    font-size: 1rem;
    letter-spacing: 0.02em;
}

.voucher-hemat {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--muted);
}

.voucher-lepas {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    cursor: pointer;
}

.voucher-kabar {
    margin-top: 6px;
}

.cart-line--diskon .cart-line-amount {
    color: var(--ink);
}

/* Ongkir + Total ngikutin kurir yang dicentang — TANPA JS, murni :has().
   Aturannya ditulis buat 12 opsi pertama; lebih dari itu tetap kepilih dan
   tetap dihitung benar di server, cuma barisnya nggak ikut ganti. */
.ship-dyn {
    display: none;
}

.checkout-layout:has(#ship-0:checked) .ship-dyn--0,
.checkout-layout:has(#ship-1:checked) .ship-dyn--1,
.checkout-layout:has(#ship-2:checked) .ship-dyn--2,
.checkout-layout:has(#ship-3:checked) .ship-dyn--3,
.checkout-layout:has(#ship-4:checked) .ship-dyn--4,
.checkout-layout:has(#ship-5:checked) .ship-dyn--5,
.checkout-layout:has(#ship-6:checked) .ship-dyn--6,
.checkout-layout:has(#ship-7:checked) .ship-dyn--7,
.checkout-layout:has(#ship-8:checked) .ship-dyn--8,
.checkout-layout:has(#ship-9:checked) .ship-dyn--9,
.checkout-layout:has(#ship-10:checked) .ship-dyn--10,
.checkout-layout:has(#ship-11:checked) .ship-dyn--11 {
    display: block;
}

.checkout-layout:has(.ship-radio:checked) .ship-ringkas--kosong {
    display: none;
}

/* --------------------------------------------- metode bayar (Kanvas)
 *
 * Blok baca-saja: pembeli milih metodenya di halaman Snap. Diam — badge
 * cuma garis rambut, tanpa logo merek (kita nggak punya lisensinya).
 */

.pay-block {
    margin: 0 0 22px;
    padding: 18px;
    border: 1px solid var(--hairline);
}

.pay-block > .checkout-heading {
    margin-bottom: 6px;
}

.pay-note {
    margin: 0 0 14px;
    font-size: 0.8rem;
    color: var(--muted);
}

.pay-list {
    margin: 0;
    display: grid;
    gap: 12px;
}

.pay-row {
    display: grid;
    gap: 6px;
}

.pay-group {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--muted);
}

.pay-items {
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

/* TANPA garis kotak, dan itu disengaja.
   Sebelumnya badge ini digambar sebagai kotak bergaris — bentuk yang sama
   persis dengan chip yang bisa dipilih — jadi pembeli mencoba mengkliknya.
   Padahal metode pembayaran dipilih nanti di halaman Midtrans; daftar ini
   cuma keterangan. Bentuknya sekarang teks, bukan kontrol. */
.pay-badge {
    padding: 0;
    border: 0;
    font-size: 0.78rem;
    color: var(--muted);
    cursor: default;
}

.pay-badge + .pay-badge::before {
    content: '·';
    margin: 0 0.45rem 0 0.1rem;
    color: var(--hairline);
}

/*
 * Baris persetujuan di atas tombol bayar. Kanvas TANPA warna aksen (§2), jadi
 * tautannya tinta bergaris bawah — diam, tapi jelas bisa diklik.
 */
.checkout-consent {
    margin: 20px 0 12px;
    padding-top: 14px;
    border-top: 1px solid var(--hairline);
    font-size: 0.8125rem;
    line-height: 1.5;
    color: var(--muted);
}

.checkout-consent a {
    color: var(--ink);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.checkout-consent a:hover {
    color: var(--ink-hover);
    text-decoration-thickness: 2px;
}

.checkout-legal {
    margin: 12px 0 0;
    font-size: 0.75rem;
    color: var(--muted);
}

.checkout-done {
    display: grid;
    justify-items: center;
    gap: 14px;
    text-align: center;
    padding-block: clamp(20px, 5vw, 56px);
}

.checkout-done-copy {
    margin: 0;
    max-width: 52ch;
    color: var(--muted);
}

/* --------------------------------------------- lacak pesanan (Kanvas)
 *
 * Diam: kode pesanan jadi satu-satunya elemen bersuara, timeline pakai
 * titik + garis rambut. Tanpa warna aksen (§2A).
 */

.order-code {
    display: grid;
    gap: 4px;
    padding: 16px 26px;
    border: 1px solid var(--ink);
}

.order-code-label {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--muted);
}

.order-code-value {
    font-family: var(--display);
    font-weight: 600;
    font-size: 1.5rem;
    letter-spacing: -0.01em;
    font-variant-numeric: tabular-nums;
}

.lacak-form {
    max-width: 26rem;
}

/* Timeline status: satu baris titik, yang sudah lewat jadi tinta penuh. */
.track {
    list-style: none;
    margin: 0 0 10px;
    padding: 0;
    display: grid;
    /* Kolom sebanyak langkahnya, lebar sama rata — tanpa nyebut angka 5,
       biar timeline nggak ikut goyang kalau statusnya nambah. */
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 4px;
}

.track-step {
    display: grid;
    justify-items: center;
    gap: 8px;
    position: relative;
    padding-top: 4px;
    color: var(--muted);
}

/* Garis penghubung antar titik. */
.track-step::before {
    content: '';
    position: absolute;
    top: 9px;
    left: -50%;
    width: 100%;
    height: 1px;
    background: var(--hairline);
}

.track-step:first-child::before {
    display: none;
}

.track-dot {
    width: 11px;
    height: 11px;
    border-radius: 50%;
    border: 1px solid var(--hairline);
    background: var(--bg);
    position: relative;
    z-index: 1;
}

.track-label {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    text-align: center;
}

.track-step--done {
    color: var(--ink);
}

.track-step--done .track-dot {
    background: var(--ink);
    border-color: var(--ink);
}

.track-step--done::before {
    background: var(--ink);
}

.track-now {
    margin: 0 0 26px;
    font-size: 0.88rem;
    color: var(--muted);
}

.order-block {
    margin-bottom: 26px;
    padding: 20px;
    border: 1px solid var(--hairline);
}

.order-track-link {
    margin: 12px 0 0;
}

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

.sf-footer {
    margin-top: clamp(40px, 7vw, 90px);
    border-top: 1px solid var(--hairline);
}

.sf-footer-grid {
    display: grid;
    gap: 28px;
    padding-block: clamp(32px, 5vw, 56px);
}

@media (min-width: 720px) {
    .sf-footer-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 40px;
    }
}

.sf-footer-brand {
    margin: 0 0 8px;
    font-family: var(--display);
    font-weight: 600;
    font-size: 1.1rem;
    letter-spacing: -0.02em;
}

.sf-footer-heading {
    margin: 0 0 10px;
    font-size: 0.7rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.12em;
}

.sf-footer-note {
    margin: 0;
    max-width: 44ch;
    font-size: 0.85rem;
    color: var(--muted);
}

.sf-footer-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 6px;
    font-size: 0.88rem;
}

.sf-footer-list a {
    color: var(--muted);
    text-decoration: none;
}

.sf-footer-list a:hover {
    color: var(--ink);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.sf-footer-bottom {
    border-top: 1px solid var(--hairline);
    padding-block: 18px;
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--muted);
}

.sf-footer-bottom p {
    margin: 0;
}

/* ---------------------------------------------------------- motion only */

@media (prefers-reduced-motion: no-preference) {
    .btn,
    .btn-remove,
    .form-input,
    .sf-nav-link,
    .sf-cart-link,
    .sf-footer-list a {
        transition: background-color 160ms ease, color 160ms ease, border-color 160ms ease;
    }

    /* Signature Kanvas interaction: the photo breathes on hover. */
    .product-media img {
        transition: transform 400ms cubic-bezier(0.2, 0.6, 0.2, 1);
    }

    .product-card:hover .product-media img {
        transform: scale(1.04);
    }

    /* Following a thumbnail link glides instead of jumping. */
    .galeri-strip {
        scroll-behavior: smooth;
    }
}

/* =========================================================== BAGIAN (§2A)
 *
 * Halaman depan yang disusun penjual (store_sections). Aturannya sama kayak
 * seluruh Kanvas: diam, garis rambut, tanpa warna aksen — yang jualan tetap
 * foto dan ruang. Semua bagian dipakai bareng ritme .sf-section yang sudah
 * ada, jadi jaraknya konsisten sama grid katalog.
 *
 * TANPA JS: nggak ada yang butuh script. <details> buat FAQ, <a> buat kontak.
 */

/* ------------------------------------------------ kolom grid opsional
 *
 * Cuma aktif kalau penjual milih jumlah kolom. Tanpa modifier, .product-grid
 * tetap pakai ritme responsif bawaan template — itu yang bikin toko yang
 * nggak pernah buka Tata Letak tampil persis kayak sebelumnya.
 */

.product-grid--kolom-2 {
    --sf-kolom: 2;
}

.product-grid--kolom-3 {
    --sf-kolom: 3;
}

.product-grid--kolom-4 {
    --sf-kolom: 4;
}

.product-grid--kolom-5 {
    --sf-kolom: 5;
}

@media (min-width: 1080px) {
    .product-grid[class*="product-grid--kolom-"] {
        grid-template-columns: repeat(var(--sf-kolom), minmax(0, 1fr));
    }
}

/* -------------------------------------------------------- hero bergambar */

.hero--bergambar {
    position: relative;
    isolation: isolate;
}

.hero-bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: -1;
}

/* Kerudung tipis: foto apa pun bisa diunggah penjual, dan teks putih di atas
   foto terang itu nggak kebaca. 0.34 cukup buat ngunci kontras tanpa bikin
   fotonya jadi abu-abu. */
.hero--bergambar .hero-overlay {
    background: rgba(17, 17, 20, 0.34);
    color: #FFFFFF;
    padding: clamp(28px, 5vw, 56px);
}

.hero--bergambar .hero-title,
.hero--bergambar .hero-sub,
.hero--bergambar .sf-eyebrow {
    color: #FFFFFF;
}

/* -------------------------------------------------------- banner promo
 *
 * Di Kanvas, "warna" diterjemahin jadi bahasa Kanvas: tinta solid atau garis
 * rambut. Kuning promo pun cuma jadi garis kiri, bukan blok neon — palet
 * template yang menang, bukan selera warna per toko.
 */

.sf-banner {
    padding-block: 18px;
    border-block: 1px solid var(--hairline);
}

.sf-banner-isi {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: center;
    gap: 8px 18px;
    text-align: center;
}

.sf-banner-teks {
    margin: 0;
    font-size: 0.9rem;
    letter-spacing: 0.01em;
}

.sf-banner-tombol {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: inherit;
    text-decoration: none;
    border-bottom: 1px solid currentColor;
    padding-bottom: 2px;
}

.sf-banner-tombol:hover {
    opacity: 0.7;
}

.sf-banner--tinta {
    background: var(--ink);
    color: #FFFFFF;
    border-color: var(--ink);
}

.sf-banner--aksen {
    background: var(--ink);
    color: #FFFFFF;
    border-color: var(--ink);
}

.sf-banner--promo {
    background: var(--bg);
    border-left: 3px solid #E8C000;
}

.sf-banner--netral {
    background: var(--wash);
}

/* ------------------------------------------------------------ teks/faq */

.sf-teks {
    /* Batas nyaman baca. Paragraf selebar 1280px itu satu-satunya cara bikin
       template yang jualannya ruang kelihatan murah. */
    max-width: 62ch;
}

.sf-teks-paragraf {
    margin: 0 0 1em;
    line-height: 1.7;
    color: var(--ink);
}

.sf-teks .sf-section-title {
    margin-bottom: 18px;
}

.sf-faq {
    margin-top: 6px;
    border-top: 1px solid var(--hairline);
}

.sf-faq-item {
    border-bottom: 1px solid var(--hairline);
}

.sf-faq-tanya {
    cursor: pointer;
    padding: 14px 0;
    font-weight: 500;
    list-style: none;
}

.sf-faq-tanya::-webkit-details-marker {
    display: none;
}

.sf-faq-tanya::after {
    content: '+';
    float: right;
    color: var(--muted);
}

.sf-faq-item[open] .sf-faq-tanya::after {
    content: '\2212'; /* minus */
}

.sf-faq-tanya:focus-visible {
    outline: 2px solid var(--focus);
    outline-offset: 2px;
}

.sf-faq-jawab {
    margin: 0;
    padding: 0 0 16px;
    color: var(--muted);
    line-height: 1.7;
}

/* -------------------------------------------------------------- galeri */

.sf-galeri {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
}

@media (min-width: 720px) {
    .sf-galeri {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 20px;
    }
}

.sf-galeri-item {
    margin: 0;
}

.sf-galeri-item img {
    display: block;
    width: 100%;
    /* Rasio yang sama kayak kartu produk: halaman ini satu bahasa. */
    aspect-ratio: 4 / 5;
    object-fit: cover;
    background: var(--wash);
}

/* -------------------------------------------------------------- kontak */

.sf-kontak-wa {
    margin-top: 6px;
}

.sf-kontak-jam {
    margin: 14px 0 0;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--muted);
}

/* Tombol mati yang bukan <button>: dipakai saat toko belum bisa menerima
   pembayaran. Dibuat sebagai <span> supaya tidak bisa difokus keyboard —
   tautan yang tidak menuju ke mana pun tetap bisa ditekan Enter. */
.btn-disabled {
    opacity: 0.55;
    cursor: not-allowed;
    pointer-events: none;
    display: block;
    text-align: center;
}

/* Ajakan melanjutkan pembayaran pada pesanan yang belum lunas. Ditaruh tepat
   di bawah status, karena itu pertanyaan pertama pembeli saat membuka
   pesanannya lagi: "terus bayarnya gimana?". */
.order-bayar {
    margin: 1.25rem 0 1.75rem;
    padding: 1.1rem 1.25rem;
    background: var(--wash);
    border: 1px solid var(--hairline);
}

.order-bayar__teks {
    margin: 0 0 0.85rem;
}

.order-bayar__catatan {
    margin: 0.75rem 0 0;
    font-size: 0.8125rem;
    color: var(--muted);
}
