/* okno-constitution-waveb.css — OKNO Design Constitution, Wave B composition layer.
   Scoped to body.okc-wb so it can never leak into an out-of-scope page.

   Wave A established that the palette, typography and card tokens are ALREADY unified across the
   commercial families: d3.css and its family satellites all consume the same --gs-* / --ok-* tokens.
   The remaining fragmentation is therefore compositional, not chromatic. This layer fixes composition
   only, and introduces no colour, font, gradient, radius, shadow language or component family that the
   approved system does not already contain. Every value below is a token or a value already used by
   d3.css / okno-card-system.css.

   What it does:
     1. canvas      — one container width across the families, prose held to a readable measure
     2. C1 invariant— a grid never ends in an orphan third/half-width card
     3. commerce    — an existing price line reads as a price, not as another grey paragraph
     4. affordance  — link cards get the hover/focus language the rest of the system already has
     5. rhythm      — banded sections get a crisp edge instead of a soft grey slab
     6. mobile      — intentional spacing, unbroken headings, reachable CTAs, no floating collision
*/

/* ============================ 1. canvas ============================ */
/* d3 caps the shell at 1120px, which leaves a wide dead margin on a 1440 desktop while the text inside
   is still capped separately. Widening the shell only (not the measure) uses the canvas without ever
   lengthening a line of body copy. */
@media (min-width:1280px){
  body.okc-wb .d3 .onh-wrap{max-width:1200px}
  body.okc-wb .d3-secnav__in{max-width:1200px}
}
/* Long explanatory sections are the flattest surfaces on these pages: full-width 15px paragraphs with
   no measure. Hold them to the Constitution's reading measure without touching grid/card content. */
@media (min-width:1001px){
  body.okc-wb .d3-sec > .onh-wrap > .d3-p,
  body.okc-wb .d3-sec > .onh-wrap > .d3-list,
  body.okc-wb .d3-sec > .onh-wrap > .d3-h3{max-width:78ch}
}
/* A little more air between a section heading and its body, so sections read as blocks. */
body.okc-wb .d3-sec > .onh-wrap > .d3-h2{margin-bottom:14px}
body.okc-wb .d3-sec > .onh-wrap > .d3-h2 + .d3-lead{margin-top:0}

/* ====================== 2. C1 invariant: no orphan card ====================== */
/* An incomplete last row is the single most common defect across these families: 7 cards in a 2-up
   grid, 5 in a 3-up, 4 in a 3-up. The lone card reads as an accident. Instead of leaving a hole, the
   trailing card becomes a deliberate full-width closer laid out horizontally — the same
   feature-composition idea the Constitution defines, expressed on the existing .d3-card markup so no
   new component family is created. */
body.okc-wb .okc-wb-span{grid-column:1/-1}
@media (min-width:641px){
  /* 2-up: a trailing card that starts its own row */
  body.okc-wb .d3-grid--2 > :last-child:nth-child(odd){grid-column:1/-1}
  /* 3-up / 4-up collapse to 2-up between 641 and 1000, so the same odd rule applies there */
  body.okc-wb .d3-grid--3 > :last-child:nth-child(odd),
  body.okc-wb .d3-grid--4 > :last-child:nth-child(odd){grid-column:1/-1}
}
@media (min-width:1001px){
  /* restore 3-up/4-up semantics above the collapse breakpoint */
  body.okc-wb .d3-grid--3 > :last-child:nth-child(odd),
  body.okc-wb .d3-grid--4 > :last-child:nth-child(odd){grid-column:auto}
  /* one card alone on the last row -> full-width closer */
  body.okc-wb .d3-grid--3 > :last-child:nth-child(3n+1){grid-column:1/-1}
  body.okc-wb .d3-grid--4 > :last-child:nth-child(4n+1){grid-column:1/-1}
  /* two cards on the last row of a 3-up -> feature + companion, so the row is complete and
     deliberately unequal rather than left with a hole */
  body.okc-wb .d3-grid--3 > :nth-last-child(2):nth-child(3n+1){grid-column:span 2}
}
/* The sitewide card grid (okno-card-system) is used for related-content rows on these same pages and
   has exactly the same orphan problem. Its breakpoints differ from d3's, so they are matched here
   rather than reused. The system already ships an .ok-card--span2 modifier, so spanning is native. */
@media (min-width:1024px){
  body.okc-wb .ok-cardgrid > :last-child:nth-child(3n+1){grid-column:1/-1}
  body.okc-wb .ok-cardgrid > :nth-last-child(2):nth-child(3n+1){grid-column:span 2}
}
@media (min-width:681px) and (max-width:1023px){
  body.okc-wb .ok-cardgrid > :last-child:nth-child(odd){grid-column:1/-1}
}

/* Horizontal composition for a card that now spans the full row: copy left, action right, so a wide
   card does not read as a stretched narrow one. The action is simply the card's last element, whatever
   the family calls it (.d3-card__foot, .fam-item__go, .lg-item__go, a button) — a trailing paragraph is
   copy, not an action, so it stays in the copy column. Cards carrying media keep their own layout. */
@media (min-width:781px){
  body.okc-wb .d3-grid--2 > .d3-card:last-child:nth-child(odd):not(:has(.d3-pic)),
  body.okc-wb .d3-grid--3 > .d3-card:last-child:nth-child(3n+1):not(:has(.d3-pic)),
  body.okc-wb .d3-grid--4 > .d3-card:last-child:nth-child(4n+1):not(:has(.d3-pic)){
    display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:36px;align-items:center}
  body.okc-wb .d3-grid--2 > .d3-card:last-child:nth-child(odd):not(:has(.d3-pic)) > *,
  body.okc-wb .d3-grid--3 > .d3-card:last-child:nth-child(3n+1):not(:has(.d3-pic)) > *,
  body.okc-wb .d3-grid--4 > .d3-card:last-child:nth-child(4n+1):not(:has(.d3-pic)) > *{
    grid-column:1;max-width:76ch}
  body.okc-wb .d3-grid--2 > .d3-card:last-child:nth-child(odd):not(:has(.d3-pic)) > :last-child:not(p),
  body.okc-wb .d3-grid--3 > .d3-card:last-child:nth-child(3n+1):not(:has(.d3-pic)) > :last-child:not(p),
  body.okc-wb .d3-grid--4 > .d3-card:last-child:nth-child(4n+1):not(:has(.d3-pic)) > :last-child:not(p){
    grid-column:2;grid-row:1/-1;align-self:center;justify-self:end;
    margin-top:0;padding-top:0;border-top:0;white-space:nowrap}
}

/* ====================== 3. the price is a price ====================== */
/* These cards already carry a price, but as another 14px grey paragraph indistinguishable from the
   description. The class is added to the EXISTING paragraph — the text itself is never touched. */
body.okc-wb .okc-wb-price{
  margin-top:auto;padding-top:10px;border-top:1px solid var(--ok-card-line);
  font-size:15px;font-weight:800;color:var(--gs-navy)}
body.okc-wb .d3-card > .okc-wb-price + .d3-card__foot,
body.okc-wb .d3-card > .okc-wb-price + .fam-item__go{margin-top:10px;padding-top:0}
/* When a card has a price, the trailing link should not also claim the auto margin. */
body.okc-wb .d3-card:has(.okc-wb-price) .d3-card__foot{margin-top:10px}

/* ====================== 4. affordance on link cards ====================== */
/* .d3-card has no hover state at all today, so a clickable card feels like a static box. This is the
   same transition/lift/border language okno-card-system and the Constitution already use. */
body.okc-wb a.d3-card{transition:box-shadow 150ms,transform 150ms,border-color 150ms}
body.okc-wb a.d3-card:hover{
  box-shadow:0 6px 20px rgba(13,124,107,.10);transform:translateY(-2px);border-color:var(--gs-teal)}
body.okc-wb a.d3-card:focus-visible{outline:3px solid var(--ok-focus,#7fd1c3);outline-offset:2px}
@media (prefers-reduced-motion:reduce){
  body.okc-wb a.d3-card{transition:none}
  body.okc-wb a.d3-card:hover{transform:none}
}
/* A card inside a card produces a double border; keep one flat surface (Constitution C1). */
body.okc-wb .d3-card .d3-card,
body.okc-wb .d3-panel .d3-panel{border:0;background:transparent;padding:0;border-radius:0}

/* ====================== 5. section rhythm ====================== */
/* Banded sections are the approved device for rhythm (d3.css already defines .d3-sec.onh-band).
   A hairline gives the band a defined edge instead of a soft grey slab. */
body.okc-wb .d3-sec.onh-band{
  box-shadow:inset 0 1px 0 var(--ok-card-line),inset 0 -1px 0 var(--ok-card-line)}
/* Two adjacent bands must not merge into one tall grey block. */
body.okc-wb .d3-sec.onh-band + .d3-sec.onh-band{box-shadow:inset 0 -1px 0 var(--ok-card-line)}

/* A text-only hero must not run the full 1200px canvas. */
body.okc-wb .d3-hero__grid:not(:has(.d3-pic)):not(:has(.d3-hero__media)) .d3-hero__copy,
body.okc-wb .d3-hero > .onh-wrap > .d3-hero__copy{max-width:820px}

/* ====================== 6. mobile ====================== */
@media (max-width:640px){
  /* A very long Russian/Ukrainian compound can overflow a 360-390 heading. break-word only splits a
     word that genuinely cannot fit; `anywhere` plus `hyphens:auto` would hyphenate words that wrap
     perfectly well ("иностран-ного"), which reads as a defect rather than a fix. */
  body.okc-wb .d3-h1,body.okc-wb .d3-h2,body.okc-wb .d3-h3,
  body.okc-wb .d3-card h3,body.okc-wb .okc-wb-price{overflow-wrap:break-word;hyphens:manual}
  /* intentional spacing rather than a compressed desktop */
  body.okc-wb .d3-sec{padding:28px 0}
  body.okc-wb .d3-grid{gap:14px;margin-top:4px}
  body.okc-wb .d3-card{padding:18px}
  body.okc-wb .d3-card h3{font-size:16.5px;line-height:1.26}
  body.okc-wb .d3-sec > .onh-wrap > .d3-h2{margin-bottom:10px}
  /* the primary action should be reachable with one thumb, not a half-width pill */
  body.okc-wb .d3-hero .d3-cta-row .d3-btn{width:100%}
  body.okc-wb .d3-cta-row{gap:10px}
  /* the floating action stack sits over the end of the page; give the last surface room to clear it */
  body.okc-wb .d3-final,
  body.okc-wb .fam-final,
  body.okc-wb .d3-sec:last-of-type{padding-bottom:96px}
}
@media (max-width:390px){
  body.okc-wb .d3-h1{font-size:24px}
  body.okc-wb .d3-card{padding:16px}
}
