/* Club Confidant 閨物代購 — Shopify theme
   v4 "watercolor atelier": the world expands from the brand artwork —
   two friends on a sun-washed street, pen line + watercolor wash.
   Warm cream paper, warm brown ink, camel/trench tan, deep navy,
   rose-copper interactive ink. Elegant, quiet, boutique. */

:root{
  --cc-accent:#EFCDBC;           /* blush — decorative only: borders, washes; never text */
  --cc-accent-dark:#DFB29E;
  --cc-ink-accent:#A05C41;       /* rose copper — AA text/interactive: 5.1:1 white / 4.8:1 cream */
  --cc-ink-accent-dark:#84492F;
  --cc-navy:#3A4560;             /* the navy trousers — primary dark ink, 9.5:1 on white */
  --cc-navy-dark:#2C374E;
  --cc-camel:#C8A87E;            /* the trench coat — decorative wash */
  --cc-tint:#F9EEE7;             /* blush wash */
  --cc-bg:#FCF7F3;               /* cream paper, sampled from the artwork's ground */
  --cc-line:#EAD9CC;             /* warm hairline */
  --cc-muted:#77675C;            /* warm grey — 5.2:1 white */
  --cc-text:#362A22;             /* warm brown-black ink, from the lockup glyphs */
  --cc-white:#fff;
  --cc-sale:#B14434;
  /* legacy accent tokens (motion.css confetti etc.) re-toned into this world */
  --cc-sky:#93A3C4;              /* washed navy */
  --cc-amber:#D9B475;            /* camel gold */
  --cc-teal:#C4907A;             /* terracotta wash */
  --cc-serif:'Noto Serif TC','Songti TC','PMingLiU',serif;
  --cc-max:1180px;
  --cc-bar:64px;
  /* ONE side gutter, named, because three of them had drifted apart: cards sat 16px from the
     screen edge (.wrap 12 + .tab-panel 4), the cart icon 12px, and the category rail 2px —
     its negative margin was hand-guessed at -14 against a gutter that is actually 16. Three
     different left edges on one phone screen is what reads as "the width is weird". Anything
     that must bleed past the gutter negates this token; it never re-guesses the number. */
  --cc-page-pad:12px;
  --cc-panel-pad:4px;
  --cc-gutter:calc(var(--cc-page-pad) + var(--cc-panel-pad));
  --cc-radius-sm:6px;
  --cc-radius-md:10px;
  --cc-radius-lg:16px;
  --cc-radius-pill:999px;
  /* hand-drawn ink frames (operator, 08-14 evening): not pills, not plain squares —
     asymmetric corner pairs read as a pen-drawn rectangle, like the artwork's linework */
  --cc-sketch-sm:255px 8px 225px 10px / 10px 225px 8px 255px;
  --cc-sketch-md:16px 8px 15px 9px / 9px 15px 8px 16px;
  --cc-sketch-lg:22px 10px 20px 12px / 12px 20px 10px 22px;
  --cc-sketch-ink:1.5px solid var(--cc-accent-dark);
  --cc-shadow-sm:0 1px 3px rgba(54,42,34,.07);
  --cc-shadow-md:0 4px 16px rgba(54,42,34,.09),0 1px 3px rgba(54,42,34,.05);
  --cc-shadow-lg:0 18px 44px rgba(54,42,34,.13),0 2px 8px rgba(54,42,34,.06);
}

*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  background:var(--cc-bg);color:var(--cc-text);
  /* faint paper grain — the artwork's watercolor paper */
  background-image:
    radial-gradient(rgba(54,42,34,.016) 1px,transparent 1px),
    radial-gradient(rgba(54,42,34,.011) 1px,transparent 1px);
  background-size:22px 22px,34px 34px;
  background-position:0 0,11px 17px;
  font-family:'Noto Sans TC','NotoSansCJKtc','PingFang TC','Microsoft JhengHei',sans-serif;
  font-size:15px;line-height:1.6;-webkit-text-size-adjust:100%;
  padding-bottom:var(--cc-bar);
}
img{max-width:100%;height:auto;display:block}
a{color:inherit;text-decoration:none}
.wrap{max-width:var(--cc-max);margin:0 auto;padding:0 var(--cc-page-pad)}
.visually-hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ---------- focus ---------- */
:focus-visible{outline:2px solid var(--cc-ink-accent);outline-offset:2px}

/* ---------- header — quiet paper, the script mark carries it ---------- */
.top-header{
  background:var(--cc-bg);
  border-bottom:1px solid var(--cc-line);
  padding:18px 12px 16px;
  display:flex;align-items:center;justify-content:center;
  /* Sticky so the cart icon stays reachable: this page is 106 rows long and the icon used to
     scroll away at the first product, leaving no way back to the cart until the bottom bar
     appeared — and that bar only exists once something is IN the cart. Opaque background, not
     the translucent one: 106 thumbnails scrolling under a see-through header is noise. */
  position:sticky;top:0;z-index:70;
}
/* The logo shrinks once you scroll so the sticky bar costs less height on a phone. */
@media(max-width:767px){
  .top-header{padding:10px 12px 9px}
  .top-header .logo img{max-height:30px}
}
/* clouds retired with the old sky — keep the hooks inert */
.top-header::before,.top-header::after{content:none}
.top-header .logo img{max-height:52px;width:auto}
@media(max-width:767px){.top-header .logo img{max-height:38px}}

.cart-link{
  position:absolute;right:var(--cc-gutter);top:50%;transform:translateY(-50%);
  display:flex;align-items:center;justify-content:center;
  min-width:48px;min-height:48px;color:var(--cc-text);
}
.cart-link svg{width:26px;height:26px}
.cart-link .count{
  position:absolute;top:4px;right:2px;background:var(--cc-ink-accent);color:#fff;
  font-size:12px;font-weight:700;line-height:1;min-width:18px;height:18px;
  border-radius:var(--cc-radius-pill);display:flex;align-items:center;justify-content:center;padding:0 5px;
  box-shadow:var(--cc-shadow-sm);
}
.cart-link .count[hidden]{display:none}

/* ---------- banner ---------- */
.section-banner{background:var(--cc-white);line-height:0}
.section-banner img{width:100%}

/* hero styles live in hero.css — base.css deliberately carries none */

/* ---------- youtube strip ---------- */
.yt-strip{background:var(--cc-white);border-top:1px solid var(--cc-line);text-align:center;padding:10px 12px}
.yt-strip a{display:inline-flex;align-items:center;gap:8px;font-weight:700;min-height:44px}
.yt-strip svg{width:26px;height:18px;flex:0 0 auto}

/* ---------- tabs — a quiet serif register, underline carries the state ---------- */
.section-tabs{
  display:flex;width:100%;margin-top:6px;gap:0;position:relative;
  border-bottom:1px solid var(--cc-line);
}
.section-tabs .tabs{
  flex:1 1 0;background:none;color:var(--cc-muted);cursor:pointer;
  text-align:center;padding:15px 4px 13px;border:0;
  font-family:var(--cc-serif);font-weight:600;letter-spacing:.14em;
  font-size:16px;min-height:48px;transition:color .15s;
  position:relative;border-radius:0;
}
.section-tabs .tabs::after{content:none}
.section-tabs .tabs:hover{color:var(--cc-text)}
@media(max-width:575px){
  .section-tabs .tabs{font-size:14px;letter-spacing:.04em;padding:14px 2px 12px;white-space:nowrap}
}
.section-tabs .tabs.active{background:none;color:var(--cc-text)!important}
.tab-panel{display:none;background:var(--cc-white);padding:20px var(--cc-panel-pad) 30px}
.tab-panel.active{display:block}

/* ---------- 開箱 LIVE panel ---------- */
.video-panel{max-width:640px;margin:0 auto;text-align:center;padding:8px 4px 4px}
.video-embed{
  aspect-ratio:16/9;margin:0 0 18px;background:var(--cc-navy);
  border:var(--cc-sketch-ink);border-radius:var(--cc-sketch-md);
  overflow:hidden;box-shadow:var(--cc-shadow-md);
}
.video-embed iframe{width:100%;height:100%;border:0;display:block}
.yt-cta{
  display:inline-flex;align-items:center;gap:10px;
  background:var(--cc-navy);color:#fff;font-weight:700;letter-spacing:.08em;
  padding:0 26px;min-height:52px;border-radius:var(--cc-sketch-sm);
  box-shadow:0 8px 20px rgba(58,69,96,.28),0 1px 3px rgba(58,69,96,.18);
  transition:background .15s,box-shadow .15s,transform .15s;
}
.yt-cta svg{width:28px;height:20px;flex:0 0 auto}
.yt-cta:hover{background:var(--cc-navy-dark);transform:translateY(-1px);box-shadow:0 10px 24px rgba(58,69,96,.34)}
.yt-cta:active{transform:translateY(1px);box-shadow:0 3px 10px rgba(58,69,96,.24)}
.partner-links{margin-top:22px;padding-top:18px;border-top:1px solid var(--cc-line)}
.partner-note{font-size:14px;color:var(--cc-muted);margin:0 0 12px}
.partner-link{
  display:inline-flex;align-items:center;margin:0 6px 10px;
  border:var(--cc-sketch-ink);background:var(--cc-white);border-radius:var(--cc-sketch-sm);
  padding:10px 18px;font-size:14px;font-weight:600;letter-spacing:.06em;min-height:44px;
  transition:background .15s,border-color .15s,color .15s,box-shadow .15s;
}
.partner-link:hover{
  background:var(--cc-tint);border-color:var(--cc-ink-accent);color:var(--cc-ink-accent-dark);
  box-shadow:var(--cc-shadow-sm);
}

/* ---------- notice ---------- */
.notice{background:var(--cc-tint);border:1.5px solid var(--cc-accent);border-radius:var(--cc-sketch-lg);padding:14px 16px;margin:0 0 16px;font-size:14px}
/* --cc-ink-accent measures 4.49:1 on --cc-tint, which is .notice's own background — under AA
   by a hundredth. The token comment's "4.8:1 on cream" is true against --cc-bg and false here. */
.notice strong{color:var(--cc-ink-accent-dark)}
/* .notice-sub had NO rule in any stylesheet while four pages emitted it — receipt.astro,
   intent/received.astro and both checkout result pages. It rendered as unstyled body text and
   read as a bug nobody had named. */
.notice-sub{margin-top:8px;padding-top:8px;border-top:1px solid var(--cc-accent);font-size:13px;line-height:1.65;color:var(--cc-muted)}
/* Same tint ground as .notice strong, plus a real tap target: it rendered 91x19. */
.notice-sub a{color:var(--cc-ink-accent-dark);font-weight:700;display:inline-flex;align-items:center;min-height:44px}
.cutoff{font-weight:700}
.cutoff b{color:var(--cc-sale)}

/* ---------- category nav — fine-line pills, like jewellery on the counter ---------- */
.cat-nav{
  display:flex;gap:8px;overflow-x:auto;padding:8px 0 10px;margin-bottom:6px;
  /* Parked UNDER the sticky header, not at top:0 — at top:0 it shared the coordinate with a
     z-index:70 header and slid straight under it, so on a 106-row page the rail existed and
     was never once visible. catnav.js measures the header (it shrinks under 768px and its
     logo is an image, so the height is not knowable at author time); the fallback covers the
     moment before that script runs. */
  position:sticky;top:var(--cc-header-h,56px);background:var(--cc-white);z-index:20;
  -webkit-overflow-scrolling:touch;scrollbar-width:none;
  box-shadow:0 6px 12px -8px rgba(54,42,34,.12);
  /* right-edge fade signals more pills off-screen (hidden scrollbar otherwise gives no cue) */
  -webkit-mask-image:linear-gradient(to right,#000 0,#000 calc(100% - 34px),transparent 100%);
  mask-image:linear-gradient(to right,#000 0,#000 calc(100% - 34px),transparent 100%);
}
.cat-nav::-webkit-scrollbar{display:none}
.cat-nav a{
  flex:0 0 auto;border:var(--cc-sketch-ink);background:var(--cc-white);
  border-radius:var(--cc-sketch-sm);
  padding:9px 16px;font-size:14px;font-weight:600;letter-spacing:.06em;white-space:nowrap;min-height:44px;
  display:flex;align-items:center;
  transition:background .15s,border-color .15s,color .15s,box-shadow .15s;
}
.cat-nav a:hover{background:var(--cc-tint);border-color:var(--cc-ink-accent);color:var(--cc-ink-accent-dark)}
.cat-nav a.on{
  background:var(--cc-ink-accent);border-color:var(--cc-ink-accent);color:#fff;
  box-shadow:0 6px 14px rgba(160,92,65,.28);
}
.cat-nav a .n{
  color:var(--cc-muted);font-weight:600;margin-left:8px;font-size:12px;
  font-variant-numeric:tabular-nums;
  transition:color .15s;
}
.cat-nav a:hover .n{color:var(--cc-ink-accent)}
.cat-nav a.on .n{color:rgba(255,255,255,.85);background:none}

/* watercolor category vignette — the full illustration, never cropped */
.cat-art{
  margin:34px auto -14px;max-width:460px;overflow:hidden;
  border:var(--cc-sketch-ink);border-radius:var(--cc-sketch-md);
  box-shadow:var(--cc-shadow-sm);background:var(--cc-white);
}
.cat-art img{width:100%;height:auto;display:block}
@media(max-width:575px){.cat-art{max-width:82%}}

.cat-head{
  display:flex;align-items:baseline;gap:12px;margin:30px 0 12px;position:relative;
  padding-bottom:9px;border-bottom:1px solid var(--cc-line);
}
/* a short rose-copper rule opens each section — the pen line from the artwork */
.cat-head::before{
  content:"";flex:0 0 26px;width:26px;height:2px;border-radius:1px;align-self:center;
  background:var(--cc-ink-accent);opacity:.75;
}
/* h1 included: /receipt's own title is the page's h1, not a section heading under one. */
.cat-head h1,.cat-head h2,.cat-head .coll-title{
  font-family:var(--cc-serif);
  font-size:clamp(1.15rem,1.05rem + 0.5vw,1.45rem);margin:0;font-weight:600;letter-spacing:.1em;
}
.cat-head span{font-size:13px;color:var(--cc-muted)}
/* the old mono kicker is retired; keep the class inert for legacy markup */
.cat-no{display:none}

/* ---------- DENSE LIST (the source's mechanism) — rows framed in pen-drawn ink ---------- */
.cc-list{display:flex;flex-direction:column;gap:10px}
.row{
  display:grid;
  grid-template-columns:72px minmax(0,1fr) auto;
  grid-template-areas:"pic info buy";
  gap:12px;align-items:center;
  padding:12px 14px;background:var(--cc-white);
  border:var(--cc-sketch-ink);border-radius:var(--cc-sketch-md);
  box-shadow:var(--cc-shadow-sm);
  position:relative;
}
/* alternate the pen stroke so the column doesn't read as a rubber stamp */
.row:nth-child(even){border-radius:9px 15px 8px 16px / 16px 8px 15px 9px}
.row.is-out{opacity:.58}
/* thumbs matted like small framed sketches (cream mat + hairline) */
.row .pic{
  grid-area:pic;position:relative;width:72px;height:72px;background:var(--cc-white);
  border:1px solid var(--cc-line);border-radius:8px;box-shadow:inset 0 0 0 3px var(--cc-white),inset 0 0 0 4px var(--cc-tint);
}
.row .pic img{width:100%;height:100%;object-fit:contain;border-radius:7px}
/* CSS 售罄 badge — a quiet ink pill; .sold (v2) and .badge-soldout share it */
.badge-soldout,.row .pic .sold{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  background:rgba(54,42,34,.85);color:#fff;
  font-size:12px;font-weight:700;letter-spacing:.12em;line-height:1;white-space:nowrap;
  padding:6px 13px;border-radius:8px 3px 7px 4px / 4px 7px 3px 8px;box-shadow:var(--cc-shadow-sm);
}
.badge-soldout::after,.row .pic .sold::after{content:none}

.row .info{grid-area:info;min-width:0}
.row .name{
  font-size:14px;font-weight:700;line-height:1.4;margin:0 0 2px;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.row .name button{
  background:none;border:0;padding:0;font:inherit;color:inherit;text-align:left;cursor:pointer;
}
.row .name button:hover{color:var(--cc-ink-accent)}
.row .spec{font-size:12px;color:var(--cc-muted);line-height:1.35;
  display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden}
.row .prices{display:flex;align-items:baseline;gap:7px;flex-wrap:wrap;margin-top:3px}
.row .price{
  color:var(--cc-ink-accent);font-size:16px;font-weight:800;
  font-variant-numeric:tabular-nums;letter-spacing:-.01em;
}
/* 優惠價 — a fine-line blush pill, tail retired with the balloons */
.row .sale-tag{
  position:relative;color:var(--cc-ink-accent);background:var(--cc-tint);
  font-size:12px;font-weight:700;border:1px solid var(--cc-accent);
  padding:1px 9px;border-radius:8px 3px 7px 4px / 4px 7px 3px 8px;
}
.row .sale-tag::after{content:none}
.row .compare{color:var(--cc-muted);text-decoration:line-through;font-size:12px}
/* The supplier list price on a crawled OEM round. Muted like .compare, but NOT struck
   through: a strikethrough reads as a former price, and this is a reference in another
   currency that was never charged. */
.row .srcprice{color:var(--cc-muted);font-size:12px;white-space:nowrap}
.row .stockline{font-size:12px;color:var(--cc-muted);margin-top:2px}
.row .stockline.low{color:var(--cc-sale);font-weight:700}

.row .buy{grid-area:buy;display:flex;flex-direction:column;align-items:flex-end;gap:6px}
.countbox{
  display:flex;align-items:center;border:var(--cc-sketch-ink);height:44px;
  border-radius:var(--cc-sketch-sm);overflow:hidden;background:var(--cc-white);
}
.countbox button{
  width:44px;height:44px;min-width:44px;min-height:44px;border:0;background:var(--cc-tint);color:var(--cc-ink-accent);
  font-size:20px;font-weight:700;line-height:1;cursor:pointer;font-family:inherit;
  transition:background .12s,color .12s;
}
.countbox button:hover{background:var(--cc-ink-accent);color:#fff}
.countbox button:disabled{opacity:.4;cursor:not-allowed}
.countbox input{
  width:46px;min-width:3ch;height:44px;border:0;text-align:center;font-weight:700;
  /* 16px, not 15: iOS Safari zooms the whole page when a focused input is under 16px, which
     throws the customer out of the layout mid-purchase. Measured at 390px on iPhone 13. */
  font-size:16px;
  font-family:inherit;
  font-variant-numeric:tabular-nums;-moz-appearance:textfield;
}
.countbox input::-webkit-outer-spin-button,.countbox input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}

/* Sketched button system (operator, 08-14 evening): a pen-drawn outline on paper,
   watercolor wash floods in on hover, press settles it into solid ink.
   Press feedback comes from .m-press (motion.css) + a gentle settle here. */
.btn-add{
  cursor:pointer;background:var(--cc-white);color:var(--cc-ink-accent-dark);font-weight:700;
  font-size:14px;font-family:inherit;padding:0 20px;min-height:44px;min-width:96px;
  letter-spacing:.1em;border:1.5px solid var(--cc-ink-accent);border-radius:var(--cc-sketch-sm);
  box-shadow:0 4px 12px rgba(160,92,65,.14),0 1px 3px rgba(160,92,65,.12);
  transition:background .15s,color .15s,border-color .15s,box-shadow .15s,transform .15s;
}
.btn-add:hover{
  background:linear-gradient(135deg,var(--cc-tint) 0%,var(--cc-accent) 100%);
  color:var(--cc-ink-accent-dark);transform:translateY(-1px);
  box-shadow:0 8px 18px rgba(160,92,65,.24),0 2px 5px rgba(160,92,65,.16);
}
.btn-add.m-press:active,.btn-add:active{
  background:var(--cc-ink-accent);border-color:var(--cc-ink-accent);color:#fff;
  transform:translateY(1px);
  box-shadow:0 2px 8px rgba(160,92,65,.22);
}
.btn-add[disabled]{
  background:var(--cc-white);border-color:var(--cc-line);color:var(--cc-muted);
  cursor:not-allowed;box-shadow:none;letter-spacing:.04em;
}
.row .subtotal{font-size:12px;color:var(--cc-text);font-weight:700;min-height:1.2em}
.row .subtotal[hidden]{visibility:hidden}
.cap-note{font-size:12px;color:var(--cc-sale);margin-top:2px}
/* Cart-line 移除. A word, not an ×: at 12px a glyph beside a stepper reads as "clear the
   number", and this deletes the line. Quiet until hovered — removing is not the thing the
   page wants you to do. 44px of height because the visible text is only ~14px tall. */
.row .line-remove{
  border:0;background:none;padding:0 4px;min-height:44px;cursor:pointer;
  font:inherit;font-size:12px;color:var(--cc-muted);text-decoration:underline;
  text-underline-offset:3px;transition:color .12s;
}
.row .line-remove:hover{color:var(--cc-sale)}
.row .line-remove:disabled{opacity:.4;cursor:not-allowed}

@media(max-width:575px){
  .row{grid-template-columns:88px minmax(0,1fr);
       grid-template-areas:"pic info" "buy buy";row-gap:10px;gap:12px;padding:14px}
  /* A 64px thumbnail of a ring is a grey smudge. 88px is the largest that still leaves the
     name two readable lines beside it at 390px — but the double inset ring (3px white +
     1px tint) ate 8px of it, and with object-fit:contain the photo then letterboxed inside
     what was left, so an 88px frame showed a ~60px picture. The frame goes on the phone; the
     photo gets the whole box. contain stays: a cropped ring is not the ring. */
  .row .pic{width:88px;height:88px;box-shadow:none;padding:2px}
  .row .pic img{width:100%;height:100%}
  .row .name{font-size:15px;-webkit-line-clamp:3}

  /* WRAP. Without it .cap-note and .row-msg are flex items competing with 加入 for the same
     line: their flex-basis:100% cannot take effect, so a two-clause cap message ("購物車已有
     3 件，已達上限") squeezed the button to a sliver and wrapped itself over four lines. Both
     now drop to their own full-width line under the controls, which is where a sentence goes. */
  .row .buy{flex-flow:row wrap;align-items:center;justify-content:flex-start;
            width:100%;gap:8px 10px}
  .row .countbox{flex:0 0 auto}
  .row .btn-add{flex:1 1 auto;min-width:132px;margin-left:0}
  .row .subtotal{flex:0 0 auto;margin-left:auto;text-align:right}
  /* Cart page: the stepper takes the left of the row, 移除 the far right, so a thumb aiming
     for − is nowhere near the control that deletes the line. */
  .row .line-remove{flex:0 0 auto;margin-left:auto}
  /* order keeps these last however the DOM is built — .row-msg is appended at runtime. */
  .row .cap-note,.row .row-msg{flex:1 0 100%;order:9;margin:0;text-align:left}

  /* Touch target, and room for a long option label. */
  .row .variant-pick{gap:6px}
  .row .variant-pick select{flex:1 1 auto;min-height:44px}
}

/* ---------- modal (detail without leaving the page) ---------- */
.cc-modal[hidden]{display:none}
.cc-modal{position:fixed;inset:0;z-index:80;display:flex;align-items:flex-end;justify-content:center}
.cc-modal .veil{position:absolute;inset:0;background:rgba(44,55,78,.42)}
.cc-modal .sheet{
  position:relative;background:var(--cc-white);width:100%;max-width:760px;
  max-height:88vh;overflow-y:auto;padding:18px;
  border-radius:var(--cc-radius-lg) var(--cc-radius-lg) 0 0;box-shadow:var(--cc-shadow-lg);
}
@media(min-width:768px){
  .cc-modal{align-items:center}
  .cc-modal .sheet{max-height:82vh;border-radius:var(--cc-sketch-lg);border:var(--cc-sketch-ink)}
}
.cc-modal .close{
  position:sticky;top:0;float:right;margin:-6px -6px 0 0;
  width:44px;height:44px;border:0;background:var(--cc-white);
  font-size:26px;line-height:1;cursor:pointer;color:var(--cc-text);z-index:2;
}
.cc-modal .m-img{
  width:min(260px,60%);margin:0 auto 12px;border-radius:var(--cc-radius-md);
  border:1px solid var(--cc-line);background:var(--cc-white);object-fit:contain;
}
.cc-modal .m-img[hidden]{display:none}
.cc-modal h2{font-family:var(--cc-serif);font-size:18px;font-weight:600;letter-spacing:.04em;margin:0 0 8px;padding-right:44px}
.cc-modal .m-prices{display:flex;align-items:baseline;gap:8px;margin-bottom:12px}
.cc-modal .m-price{color:var(--cc-ink-accent);font-size:22px;font-weight:700}
.cc-modal .m-compare{color:var(--cc-muted);text-decoration:line-through;font-size:14px}
.cc-modal .m-body{border-top:1px solid var(--cc-line);padding-top:12px}
.cc-modal .m-actions{
  position:sticky;bottom:0;background:var(--cc-white);border-top:1px solid var(--cc-line);
  padding:10px 0 0;margin-top:14px;display:flex;gap:10px;align-items:center;
}

/* ---------- spec block (extracted text, replaces raster images) ---------- */
.spec-block{font-size:14px;line-height:1.75}
.spec-block h3{
  font-size:13px;font-weight:700;color:var(--cc-ink-accent);
  margin:16px 0 6px;padding-bottom:4px;border-bottom:1px solid var(--cc-line);
}
.spec-block h3:first-child{margin-top:0}
.spec-block p{margin:0 0 10px}
.spec-block ul{margin:0 0 10px;padding-left:1.2em}
.spec-block dl{display:grid;grid-template-columns:auto 1fr;gap:4px 14px;margin:0 0 10px}
.spec-block dt{font-weight:700;color:var(--cc-muted);white-space:nowrap}
.spec-block dd{margin:0}
.spec-block table{width:100%;border-collapse:collapse;font-size:13px;margin:0 0 10px}
.spec-block th,.spec-block td{border-bottom:1px solid var(--cc-line);padding:5px 6px;text-align:left}
.spec-block th{color:var(--cc-muted);font-weight:700}
.spec-block td:last-child{text-align:right;white-space:nowrap}
.spec-block .fineprint{font-size:12px;color:var(--cc-muted)}
/* description bodies may still embed the legacy raster images with baked-in text —
   the all-text rule hides them everywhere the description renders (PDP + modal) */
.spec-block img{display:none}

/* ---------- watercolor HK pickup map ---------- */
.hk-map{
  max-width:720px;margin:0 auto 20px;padding:6px;
  background:var(--cc-bg);border:var(--cc-sketch-ink);border-radius:var(--cc-sketch-lg);
  box-shadow:var(--cc-shadow-md);
}
.hk-map img{width:100%;height:auto;display:block;border-radius:14px 7px 12px 8px / 8px 12px 7px 14px}

/* ---- map pins: real HTML text over a text-free map (2026-08-17) ----
   The labels used to be baked into hk-map.jpg. They are now positioned here in percentages
   of the image box, which keeps 繁體中文 crisp at any DPR, selectable and translatable, and
   satisfies MOTION-CONTRACT rule 8. Coordinates live in snippets/hk-map.liquid so a pin can
   be nudged without touching CSS. Never bake the labels back into the image. */
.hk-map-stage{position:relative}
.hk-pins{position:absolute;inset:0;pointer-events:none}
.hk-pin{position:absolute;left:var(--x);top:var(--y);width:0;height:0}
.hk-pin-mark{
  position:absolute;left:50%;bottom:0;transform:translateX(-50%);
  width:clamp(13px,1.45vw,19px);height:auto;
  fill:var(--cc-ink-accent);
  filter:drop-shadow(0 1px 1.5px rgba(54,42,34,.28));
}
.hk-pin-eye{fill:var(--cc-bg)}
.hk-pin-label{
  position:absolute;bottom:1px;
  font-family:var(--cc-serif);font-weight:600;
  font-size:clamp(10px,1.1vw,15px);letter-spacing:.02em;
  color:var(--cc-text);white-space:nowrap;
  /* cream halo so a label stays legible wherever it crosses the painted land */
  text-shadow:0 0 3px var(--cc-bg),0 0 5px var(--cc-bg),0 0 8px var(--cc-bg);
}
.hk-pin[data-side="right"] .hk-pin-label{left:calc(50% + 11px)}
.hk-pin[data-side="left"]  .hk-pin-label{right:calc(50% + 11px)}

.hk-map-key{
  display:flex;align-items:center;justify-content:center;gap:7px;
  margin:10px 0 2px;
  font-family:var(--cc-serif);font-size:14px;color:var(--cc-muted);
}
.hk-map-key .hk-pin-mark{position:static;transform:none;width:13px;filter:none}

/* licence credit — required by ODbL (coastline) and the DATA.GOV.HK terms (district data).
   Quiet, but present and legible. Do not hide. */
.hk-map-credit{
  margin:2px 0 0;text-align:center;
  font-size:11px;line-height:1.5;color:var(--cc-muted);
}
.hk-map-credit a{color:var(--cc-muted);text-decoration:underline;text-underline-offset:2px}

/* ---------- branches / about ---------- */
.branch-list{display:grid;grid-template-columns:repeat(2,1fr);gap:12px}
@media(max-width:767px){.branch-list{grid-template-columns:1fr}}
.branch{border:var(--cc-sketch-ink);border-radius:var(--cc-sketch-md);padding:15px 17px;background:var(--cc-white);box-shadow:var(--cc-shadow-sm)}
.branch:nth-child(even){border-radius:9px 15px 8px 16px / 16px 8px 15px 9px}
.branch h3{margin:0 0 5px;font-family:var(--cc-serif);font-weight:600;font-size:15px;letter-spacing:.04em;color:var(--cc-ink-accent)}
.branch p{margin:0 0 3px;font-size:14px}
.branch a{color:var(--cc-ink-accent);font-weight:700;display:inline-flex;align-items:center;min-height:44px}
.about{max-width:860px;margin:0 auto;line-height:1.9}
.about p{margin:0 0 14px}
.about .social a{display:inline-flex;align-items:center;min-height:44px;color:var(--cc-ink-accent);font-weight:700;word-break:break-all}

/* ---------- sticky cart bar ---------- */
.cartbar{
  position:fixed;left:0;right:0;bottom:0;z-index:60;
  background:rgba(252,247,243,.95);-webkit-backdrop-filter:saturate(1.2);backdrop-filter:saturate(1.2);
  border-top:1px solid var(--cc-accent-dark);padding:8px 12px;
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  box-shadow:0 -1px 0 rgba(54,42,34,.03),0 -12px 28px rgba(54,42,34,.07);min-height:var(--cc-bar);
}
.cartbar[hidden]{display:none}
.cartbar .total{font-weight:700;font-size:14px;line-height:1.3}
.cartbar .total span{color:var(--cc-ink-accent);font-size:19px}
.cartbar .total .cut{display:block;font-size:12px;color:var(--cc-muted);font-weight:400}
.btn-checkout{
  background:var(--cc-navy);color:#fff;padding:0 24px;font-weight:700;border:0;cursor:pointer;
  font-family:inherit;font-size:15px;min-height:48px;display:inline-flex;align-items:center;gap:8px;
  letter-spacing:.1em;border-radius:var(--cc-sketch-sm);
  box-shadow:0 8px 20px rgba(58,69,96,.28),0 1px 3px rgba(58,69,96,.18);
  transition:background .15s,box-shadow .15s,transform .15s;
}
.btn-checkout::after{content:"→";font-weight:400;transform:translateX(0);transition:transform .15s}
.btn-checkout:hover{background:var(--cc-navy-dark);transform:translateY(-1px);box-shadow:0 10px 24px rgba(58,69,96,.34)}
.btn-checkout:hover::after{transform:translateX(3px)}
.btn-checkout.m-press:active,.btn-checkout:active{
  transform:translateY(1px);
  box-shadow:0 3px 10px rgba(58,69,96,.24);
}

/* ---------- scene illustrations (the artwork's own world) ---------- */
.panel-scene{max-width:640px;margin:0 auto 18px;padding:0 4px}
.panel-scene img{
  width:100%;height:auto;border-radius:var(--cc-radius-lg);
  border:1px solid var(--cc-line);box-shadow:var(--cc-shadow-md);
}
.empty-scene{max-width:240px;margin:26px auto 6px}
.empty-scene img{width:100%;height:auto;border-radius:50%;border:3px solid var(--cc-tint);box-shadow:var(--cc-shadow-sm)}

/* the balcony railing retired with the street world; hook kept inert */
.iron-divider{display:none}

/* ---------- watercolor wash bridging into the footer ---------- */
.street-strip{line-height:0;margin-top:30px;position:relative}
.street-strip img{width:100%;height:auto;display:block}
.street-strip::before,.street-strip::after{content:none}

/* ---------- footer — the wash settles ---------- */
.bottom-footer{background:linear-gradient(180deg,#F6E7DC 0%,#FBF3EC 100%);border-top:0;margin-top:0;padding:22px 12px 18px;text-align:center}
.bottom-footer .pay{display:flex;justify-content:center;gap:10px;margin-bottom:10px}
.bottom-footer .pay img{height:24px;width:auto}
.bottom-footer-text{font-weight:700;font-size:11pt}
.bottom-footer-text a{display:inline-block;padding:8px 4px}
.bottom-footer-text a:hover{color:var(--cc-ink-accent)}
.bottom-footer .copy{color:var(--cc-muted);font-size:12px;margin-top:8px}

/* ---------- product page ---------- */
.page-wrap{background:var(--cc-white);padding:22px 0 36px;margin-top:2px}
.page-wrap h1{font-family:var(--cc-serif);font-weight:600;letter-spacing:.06em;font-size:21px;margin:0 0 16px}
.rte{line-height:1.9}

.pdp{display:grid;grid-template-columns:1fr 1fr;gap:26px;align-items:start}
@media(max-width:767px){.pdp{grid-template-columns:1fr;gap:16px}}
.pdp .media img{border:1px solid var(--cc-line);margin-bottom:10px}
.pdp .info{position:sticky;top:12px}
@media(max-width:767px){.pdp .info{position:static}}
.pdp .price{color:var(--cc-ink-accent);font-size:24px;font-weight:700}
.pdp .compare{color:var(--cc-muted);text-decoration:line-through;margin-left:8px}
.pdp .buyrow{display:flex;gap:10px;align-items:center;margin:14px 0}

.crumb{font-size:13px;color:var(--cc-muted);margin-bottom:10px}
.crumb a{color:var(--cc-ink-accent);font-weight:700}

/* ---------- cart ---------- */
table.cart{width:100%;border-collapse:collapse}
table.cart th,table.cart td{border-bottom:1px solid var(--cc-line);padding:9px 6px;text-align:left;font-size:14px}
table.cart img{width:56px}
.cart-total{text-align:right;font-size:18px;font-weight:700;margin:14px 0}
.cart-total span{color:var(--cc-ink-accent)}
.pickup-field{margin:16px 0;padding:14px;border:1.5px solid var(--cc-accent);border-radius:var(--cc-sketch-lg);background:var(--cc-tint)}
.pickup-field label{display:block;font-weight:700;margin-bottom:6px}
.pickup-field select{width:100%;padding:12px;font-family:inherit;font-size:15px;border:1px solid var(--cc-line);min-height:48px;background:#fff}
.pickup-field .req{color:var(--cc-sale)}
.empty{text-align:center;padding:36px 0;color:var(--cc-muted)}

/* ── 訂貨意向 form ────────────────────────────────────────────────────────────
   The checkout form had no styling at all. Unstyled, `<label>姓名<input></label>`
   flows inline, so at 390px each label sat beside the PREVIOUS input and a customer
   could reasonably type their email into the name box. Found by screenshotting the
   built page at phone width; it is invisible on a desktop viewport. */
.checkout-form{display:flex;flex-direction:column;gap:14px;margin:18px 0 0}
.checkout-form label{
  display:flex;flex-direction:column;gap:6px;
  font-weight:700;color:var(--cc-ink);
}
.checkout-form input,
.checkout-form select{
  /* 16px is not a style choice: iOS Safari zooms the whole page when a focused input
     is smaller, and the page never zooms back out. */
  font:inherit;font-size:16px;font-weight:400;
  min-height:44px;                    /* the touch-target floor */
  padding:10px 12px;
  border:1px solid var(--cc-line);border-radius:8px;
  background:var(--cc-white);color:var(--cc-ink);
  width:100%;box-sizing:border-box;
}
.checkout-form input:focus-visible,
.checkout-form select:focus-visible{border-color:var(--cc-ink-accent)}
.checkout-form .btn-add{margin-top:4px;min-height:48px}
.checkout-form .stockline{margin-top:2px}
.checkout-form .cap-note{color:var(--cc-ink-accent-dark);font-weight:700}
/* Country code + number on one line. The menu is sized to its longest label (中國內地 +86) and
   no wider — at 390px the number field is what needs the room, and a country menu that takes
   half the row pushes an 8-digit number into a box that shows five of them. */
.phone-field{display:flex;gap:8px;align-items:stretch}
.phone-field select{flex:0 0 auto;width:auto;min-width:8.5em;max-width:48%}
.phone-field input{flex:1 1 auto;min-width:0}

/* ── product photo lightbox ───────────────────────────────────────────────────
   The thumbnail is a <button> now, so the browser's default button chrome has to go —
   but the matted-sketch frame the .pic class draws must stay exactly as it was. */
.row button.pic{
  padding:0;margin:0;font:inherit;color:inherit;cursor:zoom-in;
  appearance:none;-webkit-appearance:none;display:block;
}
.row button.pic:focus-visible{outline:2px solid var(--cc-ink-accent);outline-offset:3px}
/* The photo-count badge sat on the bottom-right corner of every thumbnail. Removed on the
   operator's call, 2026-09-14: across 104 rows it read as clutter, and the lightbox already
   shows "1 / 4" once opened. The markup still emits it, so it is hidden rather than deleted —
   restoring it is a one-line change here. */
.row .pic-count{display:none}
.row .srclink{margin:3px 0 0}
.row .srclink a{
  font-size:12px;color:var(--cc-muted);text-decoration:underline;
  text-underline-offset:2px;text-decoration-thickness:1px;
}
.row .srclink a:hover,.row .srclink a:focus-visible{color:var(--cc-ink-accent)}

.cc-zoom[hidden]{display:none}
.cc-zoom{position:fixed;inset:0;z-index:90;display:flex;align-items:center;justify-content:center}
.cc-zoom .veil{position:absolute;inset:0;background:rgba(44,55,78,.72);cursor:zoom-out}
.cc-zoom .zoom-sheet{
  position:relative;display:flex;flex-direction:column;align-items:center;gap:10px;
  /* fit-content, not a fixed 900px: a portrait photo left the close button stranded far to the
     right of the frame it was meant to close. The sheet now hugs the figure. */
  width:fit-content;max-width:min(92vw,900px);max-height:92vh;padding:14px;
}
.cc-zoom .zoom-figure{
  margin:0;background:var(--cc-white);border-radius:var(--cc-sketch-lg);
  border:var(--cc-sketch-ink);padding:10px;box-shadow:var(--cc-shadow-sm);
  display:flex;align-items:center;justify-content:center;max-height:74vh;
}
.cc-zoom img{
  display:block;max-width:100%;max-height:70vh;width:auto;height:auto;
  object-fit:contain;border-radius:6px;
}
.cc-zoom .zoom-caption{
  margin:0;color:#fff;font-size:13px;line-height:1.5;text-align:center;
  text-shadow:0 1px 3px rgba(0,0,0,.5);
}
.cc-zoom .zoom-counter{color:rgba(255,255,255,.72);font-variant-numeric:tabular-nums}
/* 44px targets: these are the controls a thumb actually hits. */
.cc-zoom .zoom-close,.cc-zoom .zoom-prev,.cc-zoom .zoom-next{
  min-width:44px;min-height:44px;display:flex;align-items:center;justify-content:center;
  background:rgba(255,255,255,.92);color:var(--cc-ink);border:var(--cc-sketch-ink);
  /* --cc-sketch-sm is a large irregular pill; on a 44px square it reads as a blob.
     This is the badge radius — the theme's shape for small objects. */
  border-radius:8px 3px 7px 4px / 4px 7px 3px 8px;font-size:22px;line-height:1;cursor:pointer;
}
.cc-zoom .zoom-close{position:absolute;top:14px;right:14px;z-index:2}
.cc-zoom .zoom-nav{display:flex;gap:14px}
.cc-zoom .zoom-nav[hidden]{display:none}
.cc-zoom button:focus-visible{outline:2px solid #fff;outline-offset:2px}
@media (max-width:600px){
  .cc-zoom .zoom-sheet{width:100vw;padding:10px}
  .cc-zoom .zoom-figure{max-height:66vh;padding:6px}
  .cc-zoom img{max-height:62vh}
}

/* Variant selector. A real <select>: on a phone the native picker beats any custom list, and
   46 distinct option names across the catalogue ("#9", "Heart(gold)-S size") need the width. */
.row .variant-pick{display:flex;align-items:center;gap:8px;margin:4px 0 0;flex-wrap:wrap}
.row .variant-pick label{font-size:12px;color:var(--cc-muted);font-weight:700;white-space:nowrap}
.row .variant-pick select{
  font:inherit;font-size:16px;            /* 16px or iOS zooms the page on focus and never returns */
  min-height:40px;padding:6px 30px 6px 10px;max-width:100%;
  border:1px solid var(--cc-line);border-radius:8px;
  background:var(--cc-white);color:var(--cc-ink);
}
.row .variant-pick select:focus-visible{outline:2px solid var(--cc-ink-accent);outline-offset:2px}

/* A failure reason that belongs to one row. The add button is ~64px wide and cannot hold a
   sentence, so the server's message lands here instead of being thrown away. */
.row .row-msg{
  flex-basis:100%;margin:6px 0 0;font-size:12px;line-height:1.5;
  color:var(--cc-sale);font-weight:700;
}

/* ---------- category rail: jump targets and phone density ---------- */
/* A jump must land on the heading, not behind the header + rail stacked above it. */
section[id^="cat-"]{scroll-margin-top:var(--cc-jump-h,112px)}
html{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

@media(max-width:575px){
  /* Full-bleed rail: pills that run to the screen edge read as scrollable; ones inset by the
     page gutter read as a finished row that happens to be clipped. */
  /* Bleeds to the screen edge by negating the gutter token, never by re-guessing it: the
     hand-written -14 against a 16px gutter left a 2px cream sliver down both sides of an
     otherwise white bar. */
  .cat-nav{margin-inline:calc(-1 * var(--cc-gutter));
           padding:8px var(--cc-gutter) 9px;gap:6px}
  .cat-nav a{padding:8px 13px;font-size:13px;letter-spacing:.03em;min-height:40px}
  .cat-nav a .n{margin-left:6px;font-size:11px}
  /* The vignette is decoration; between the rail and the first product it costs a phone
     screen's worth of scrolling on every category. */
  .cat-art{margin:18px auto -10px;max-width:62%}
}
