/* =====================================================================
   CORE SHOPS · MERCHANDISED PATTERN CSS
   v6.1 · 22 August 2026 · owner MHL · GENERATED from the design-system document
   -----------------------------------------------------------------
   The production CSS for the four merchandised patterns, lifted verbatim from
   core-shops-design-system-v6.html so it can be dropped into a build instead of
   retyped from a specification.

     .sh-    section header (§13)      kicker + H2 + View-all
     .pc-    universal product card (§14)
     .cmp-   compare module (§15)      PLP only; ships dormant elsewhere
     .cf-    editorial category band (§16)

   REQUIRES tokens.css — every value here is a var(). Load that first:
       <link rel="stylesheet" href="tokens.css">
       <link rel="stylesheet" href="patterns.css">

   NOT INCLUDED, deliberately: the documentation's own chrome (the continuous
   canvas demo wrapper, note boxes, CSS-drawn placeholder imagery). Those exist
   to make the document a specimen, not to ship. The canvas rule itself is one
   line and belongs to your section markup:
       .your-merchandised-section { background: var(--canvas);
                                    padding-block: var(--pad-section); }

   Read §13–§17 of the document for the reasoning behind any rule here. Where a
   comment below says "measured" or names a version, that is a real finding —
   do not tidy it away.
   ===================================================================== */

/* PREREQUISITE — `box-sizing: border-box`.
   The measured geometry in §14/§16 assumes it, as the document does. Without it
   a 1140px container with 16px padding hands the grid the full 1140 instead of
   1108, and every card comes out ~11px wide: 364px instead of 353px, media
   362×271 instead of 351×263. The ratio still reads 4:3, so it looks fine and
   is silently wrong. Verified by building a page against tokens.css +
   patterns.css alone, with and without the reset.
   Most resets set it globally. This scopes it to the patterns as a safety net;
   your container needs it too — see INTEGRATION.md. */
.sh, .sh *, .pc, .pc *, .cf, .cf *, .cmp-table, .cmp-table *,
.cmp-bar, .cmp-bar *, .cmp-panel, .cmp-panel * { box-sizing: border-box; }

/* --- section header pattern (§13) --- */
.sh{margin-bottom:var(--sp-5)}
.sh__kicker{
  margin:0 0 var(--sp-3);
  font-size:var(--fs-caption);font-weight:var(--fw-bold);line-height:var(--lh-label);
  letter-spacing:.12em;text-transform:uppercase;
  color:var(--eyebrow-text);   /* 5.76:1 on the canvas — NOT --text-secondary, which fails 1.4.3 here */
}
.sh__row{display:flex;align-items:baseline;justify-content:space-between;gap:var(--sp-4);flex-wrap:wrap}
.sh__row h3{font-size:var(--fs-h1);margin:0}   /* 30px/700 — an H2 in production */
.sh__all{
  flex:0 0 auto;align-self:center;
  display:inline-flex;align-items:baseline;gap:var(--sp-2);
  min-height:44px;                              /* 2.5.8 — the row is baseline-aligned, so the target grows downward */
  font-size:var(--fs-cta);font-weight:var(--fw-bold);
  color:var(--action-secondary-text);text-decoration:none;
}
.sh__all .chev{display:inline-block;transition:transform var(--dur-base) var(--ease)}
@media (hover:hover) and (pointer:fine){ .sh__all:hover .chev{transform:translateX(2px)} }
@media (prefers-reduced-motion:reduce){ .sh__all .chev{transition:none} }
@media (max-width:767px){ .sh__row{gap:var(--sp-2)} .sh__all{flex-basis:100%} }

/* --- §14 · the universal product card ------------------------------- */
.pc-grid{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--gap-column)}
@media (min-width:768px){  .pc-grid{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (min-width:1024px){ .pc-grid{grid-template-columns:repeat(3,minmax(0,1fr))} }

.pc{
  touch-action:pan-y;                /* resolves from the hit-tested element: it must sit on the card, not on .pc-media */
  position:relative;                 /* the stretched link anchors here */
  display:flex;flex-direction:column;min-width:0;
  background:var(--bg-surface);
  border:1px solid var(--border-subtle);   /* the card is a white surface, so the hairline is permitted */
  border-radius:var(--r-sm);
  overflow:hidden;
  transition:border-color var(--dur-base) var(--ease);
}
@media (hover:hover) and (pointer:fine){
  .pc:hover{border-color:var(--border-strong)}
  .pc:hover .pc-link{color:var(--action-secondary-text)}   /* colour shift, never an underline */
}
.pc-media{
  position:relative;aspect-ratio:var(--img-product);overflow:hidden;
  background:var(--media-well);      /* §17: only correct behind TRANSPARENT renders */
  touch-action:pan-y;
}
.pc-slide{position:absolute;inset:0;opacity:0;visibility:hidden;
  transition:opacity var(--dur-base) var(--ease), visibility var(--dur-base) step-end}
.pc-slide.is-active{opacity:1;visibility:visible;transition:opacity var(--dur-base) var(--ease)}
@media (hover:hover) and (pointer:fine){
  .pc:hover .pc-slide--1{opacity:0;visibility:hidden}
  .pc:hover .pc-slide--2{opacity:1;visibility:visible}
}
@media (prefers-reduced-motion:reduce){ .pc-slide{transition:none} }
.pc-badge{
  position:absolute;top:var(--sp-3);left:var(--sp-3);z-index:2;
  padding:6px 10px;border-radius:0;
  background:var(--sale-red);color:var(--text-on-brand);
  font-size:var(--fs-cta);font-weight:var(--fw-bold);line-height:1;
  pointer-events:none;
}
.pc-dots{position:absolute;left:0;right:0;bottom:var(--sp-3);z-index:2;
  display:none;justify-content:center;gap:6px;pointer-events:none}
@media (hover:none){ .pc-dots{display:flex} }   /* indicators, not targets — touch only */
.pc-dot{width:6px;height:6px;border-radius:50%;background:rgba(255,255,255,.6);
  box-shadow:0 0 0 1px rgba(74,74,74,.35)}
.pc-dot.is-active{background:var(--action-secondary-text);box-shadow:0 0 0 1px rgba(255,255,255,.8)}
/* body rhythm: 16px sides · eyebrow→title 2px · title→spec 8px · spec→price 12px
   · price→CTA 14px · CTA→card bottom 16px. Nothing after the CTA. */
.pc-body{display:flex;flex-direction:column;flex:1 1 auto;min-width:0;padding:var(--gap-card)}
.pc-eyebrow{margin:0 0 2px;font-size:var(--fs-caption);line-height:var(--lh-label);
  letter-spacing:.08em;color:var(--text-secondary)}   /* decorative by design — see the §1 limitation */
.pc-title{font-size:var(--fs-h3);margin:0}
.pc-link{color:inherit;text-decoration:none;transition:color var(--dur-fast) var(--ease)}
.pc-link::after{content:"";position:absolute;inset:0;z-index:0}   /* the whole card is the link */
.pc-spec{margin:var(--sp-2) 0 0;font-size:var(--fs-caption);line-height:var(--lh-spec);
  color:var(--text-primary)}   /* wraps to 2 lines, never truncates: no line-clamp here */
.pc-price{
  margin-top:auto;                 /* equal heights per row: pins price+CTA to the foot */
  padding-top:var(--sp-3);
  display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--sp-2);line-height:var(--lh-tight);
}
.pc-price > *{padding:0;margin:0;background:none;border:0}   /* nothing may lift off the shared baseline */
.pc-pre{font-size:var(--fs-caption);color:var(--text-secondary)}
.pc-now{font-size:var(--fs-price);font-weight:var(--fw-bold);color:var(--sale-red)}
.pc-was{font-size:var(--fs-caption);color:var(--text-secondary);text-decoration:line-through}
.pc-cta{
  position:relative;z-index:1;      /* above the stretched link */
  display:flex;align-items:center;justify-content:center;
  width:100%;min-height:44px;margin-top:14px;padding:var(--sp-2) var(--sp-4);
  font:var(--fw-bold) var(--fs-cta)/1.2 var(--font-body);
  text-transform:none;text-decoration:none;text-align:center;
  color:var(--action-primary-text);background:var(--action-primary-bg);
  border:0;border-radius:var(--action-radius);
}
.pc-cta:hover{filter:var(--action-primary-hover)}   /* darken the fill; no third teal */

/* --- §15 · compare module (specimen fragment) ----------------------- */
.cmp-table{width:100%;border-collapse:collapse;font-size:var(--fs-caption);background:#fff}
.cmp-table th,.cmp-table td{padding:10px 12px;border-bottom:1px solid var(--border-subtle);
  text-align:left;vertical-align:top}
.cmp-table th[scope="row"]{background:var(--canvas);font-weight:var(--fw-bold);white-space:nowrap}
.cmp-hang{display:flex;align-items:flex-start;gap:var(--sp-2)}
.cmp-hang svg{flex:0 0 auto;margin-top:-2px}
.cmp-hang__1{display:block;font-size:var(--fs-caption);color:var(--text-primary);line-height:var(--lh-label)}
.cmp-hang__2{display:block;font-size:var(--fs-micro);color:var(--text-secondary);line-height:var(--lh-label)}
.cmp-cellprice{font-size:var(--fs-h3);font-weight:var(--fw-bold);color:var(--sale-red)}
.cmp-bar-demo{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-3);
  background:#fff;border-top:1px solid var(--border-strong);box-shadow:var(--shadow-3);
  padding:var(--sp-3) var(--sp-4);border-radius:var(--r-sm)}
.cmp-thumb{width:48px;height:36px;border:1px solid var(--border-subtle);border-radius:4px;
  background:linear-gradient(135deg,#dfeef0,#cfe6d6)}
.cmp-go{display:inline-flex;align-items:center;justify-content:center;min-height:44px;
  padding:var(--sp-2) var(--sp-5);font:var(--fw-bold) var(--fs-cta)/1.2 var(--font-body);
  color:var(--action-primary-text);background:var(--action-primary-bg);border:0;
  border-radius:var(--action-radius);cursor:pointer}
.cmp-clear{min-height:44px;min-width:44px;font-size:var(--fs-caption);color:var(--link-text);
  background:none;border:0;cursor:pointer;text-decoration:underline;text-underline-offset:2px}

/* --- the outlined secondary button (§19, v6.1) -----------------------
   Exists in the live estate but was never specced, so a project invented a 6%
   teal wash for its hover. The obvious fix fails: filter:brightness() on a
   TRANSPARENT button is imperceptible — there is no fill to darken. So it
   inverts. Same font shorthand and 44px min-height as .pc-cta, no
   letter-spacing of its own. */
.btn--secondary{
  display:inline-flex;align-items:center;justify-content:center;
  min-height:44px;padding:var(--sp-2) var(--sp-4);
  font:var(--fw-bold) var(--fs-cta)/1.2 var(--font-body);
  text-transform:none;text-decoration:none;text-align:center;
  color:var(--action-secondary-text);
  background:var(--action-secondary-bg);
  border:2px solid var(--action-secondary-bd);
  border-radius:var(--action-radius);
  cursor:pointer;
}
@media (hover:hover) and (pointer:fine){
  .btn--secondary:hover{
    background:var(--action-secondary-hover);   /* fill appears */
    border-color:var(--action-secondary-hover);
    color:var(--text-on-brand);                 /* 6.33:1 */
  }
}
.btn--secondary:disabled{opacity:.45;cursor:not-allowed}

/* --- §16 · editorial panel options (v6.1) ---------------------------
   Navy is the default and comes from tokens.css. These switch the whole band
   to another sanctioned option with ONE declaration — never a pasted hex. */
body[data-editorial="navy"]      { --editorial-panel:var(--panel-navy) }
body[data-editorial="greyblue"]  { --editorial-panel:var(--panel-greyblue) }
body[data-editorial="sage"]      { --editorial-panel:var(--panel-sage) }
body[data-editorial="terracotta"]{ --editorial-panel:var(--panel-terracotta) }

/* --- §16 · editorial category band --------------------------------- */
.cf-grid{display:grid;gap:var(--gap-column);align-items:start;grid-template-columns:minmax(0,1fr)}
.cf-supports{display:flex;flex-direction:column;gap:var(--gap-column);min-width:0}
@media (min-width:768px){                       /* feature full width, supports 2-up beneath */
  .cf-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .cf--feature{grid-column:1 / -1}
  .cf-supports{display:contents}
}
@media (min-width:1024px){                      /* the solved split — see the note in §16 */
  .cf-grid{grid-template-columns:minmax(0,2.24fr) minmax(0,1fr);align-items:stretch}
  .cf--feature{grid-column:auto}
  .cf-supports{display:flex;flex-direction:column;gap:var(--gap-column);min-width:0}
  .cf-supports > .cf{flex:1 1 auto}
  .cf--support .cf-body{padding:var(--sp-3) var(--sp-4)}
  .cf--feature .cf-body{display:flex;flex-direction:column;justify-content:space-between}
}
.cf{position:relative;display:flex;flex-direction:column;min-width:0;
  border:0;                          /* no hairline: this card sits on the tint */
  border-radius:var(--r-sm);overflow:hidden;
  background:var(--editorial-panel)} /* guards the radius if a child ever fails to fill the card */
.cf-media{position:relative;overflow:hidden;background:var(--editorial-panel);flex:0 0 auto;
  aspect-ratio:var(--img-category)}
.cf-media > .ph{position:absolute;inset:0}
@media (hover:hover) and (pointer:fine){ .cf:hover .cf-media .ph{transform:scale(1.04)} }
.cf-media .ph{transform:scale(1);transition:transform var(--dur-slow) var(--ease)}
.cf-body{flex:1 1 auto;background:var(--editorial-panel);color:#fff;padding:var(--sp-4)}
.cf-title{color:#fff;margin:0}
.cf--feature .cf-title{font-size:clamp(1.5rem,3.4vw,var(--fs-h1))}
.cf--support .cf-title{font-size:1.125rem}   /* 18px keeps the longest title on one line, which keeps the block on 16:9 */
@media (max-width:767px){ .cf--feature .cf-title,.cf--support .cf-title{font-size:1.5rem} }
.cf-desc{margin:var(--sp-2) 0 0;font-size:var(--fs-body);color:#fff}
.cf-go{display:inline-block;margin-top:var(--sp-2);font-size:var(--fs-cta);
  font-weight:var(--fw-bold);color:#fff;white-space:nowrap;text-decoration:none}
.cf-go .chev{display:inline-block;transition:transform var(--dur-fast) var(--ease)}
@media (hover:hover) and (pointer:fine){ .cf:hover .cf-go .chev{transform:translateX(2px)} }
.cf-link{color:inherit;text-decoration:none}
.cf-link::after{content:"";position:absolute;inset:0;z-index:0}
/* the ring must be a box-shadow on the CARD: .cf carries overflow:hidden, and
   overflow clips a descendant's outline, so an outline on the stretched link
   was painted and thrown away. */
.cf-link:focus-visible{outline:none;box-shadow:none}
.cf:focus-within{box-shadow:0 0 0 2px var(--focus-ring-inner), 0 0 0 4px var(--focus-ring)}
@supports selector(:has(*)){
  .cf:focus-within{box-shadow:none}
  .cf:has(.cf-link:focus-visible){box-shadow:0 0 0 2px var(--focus-ring-inner), 0 0 0 4px var(--focus-ring)}
}
