/* cpon: street market coupon, made premium. One stylesheet, mobile first; stage 2: logical properties, the faces per script, the store window (built by scripts/stage2/stylesheet.py from site/css/site.css). */

/* the faces per script: each claims its script's range less the invisible format characters no face of the site draws (the word joiner U+2060 among them), so no face is fetched for one (scripts/stage2/stylesheet.py, the run 12 fix of wave es) */
@font-face {
  font-family: "Sofia Sans Condensed";
  src: url("/fonts/SofiaSansCondensed-latin.woff2") format("woff2");
  font-weight: 1 1000;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-2010, U+2012-2029, U+2030-205F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FFFD;
}
@font-face {
  font-family: "Sofia Sans Condensed";
  src: url("/fonts/SofiaSansCondensed-latin-ext.woff2") format("woff2");
  font-weight: 1 1000;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-0151, U+0154-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20A9, U+20AB, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Sofia Sans Condensed";
  src: url("/fonts/SofiaSansCondensed-cyrillic.woff2") format("woff2");
  font-weight: 1 1000;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Sofia Sans Condensed";
  src: url("/fonts/SofiaSansCondensed-cyrillic-ext.woff2") format("woff2");
  font-weight: 1 1000;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: "Sofia Sans Condensed";
  src: url("/fonts/SofiaSansCondensed-greek.woff2") format("woff2");
  font-weight: 1 1000;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
@font-face {
  font-family: "Sofia Sans Condensed";
  src: url("/fonts/SofiaSansCondensed-punct.woff2") format("woff2");
  font-weight: 1 1000;
  font-style: normal;
  font-display: swap;
  unicode-range: U+2011, U+202F;
}
@font-face {
  font-family: "Hanken Grotesk";
  src: url("/fonts/HankenGrotesk-latin-normal.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-2010, U+2012-2029, U+2030-205F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FFFD;
}
@font-face {
  font-family: "Hanken Grotesk";
  src: url("/fonts/HankenGrotesk-latin-ext-normal.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-0151, U+0154-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20A9, U+20AB, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Hanken Grotesk";
  src: url("/fonts/HankenGrotesk-punct-normal.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+2011, U+202F;
}
@font-face {
  font-family: "Sofia Sans";
  src: url("/fonts/SofiaSans-latin.woff2") format("woff2");
  font-weight: 1 1000;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-2010, U+2012-2029, U+2030-205F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FFFD;
}
@font-face {
  font-family: "Sofia Sans";
  src: url("/fonts/SofiaSans-latin-ext.woff2") format("woff2");
  font-weight: 1 1000;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-0151, U+0154-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20A9, U+20AB, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Sofia Sans";
  src: url("/fonts/SofiaSans-cyrillic.woff2") format("woff2");
  font-weight: 1 1000;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Sofia Sans";
  src: url("/fonts/SofiaSans-cyrillic-ext.woff2") format("woff2");
  font-weight: 1 1000;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: "Sofia Sans";
  src: url("/fonts/SofiaSans-greek.woff2") format("woff2");
  font-weight: 1 1000;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
@font-face {
  font-family: "Sofia Sans";
  src: url("/fonts/SofiaSans-punct.woff2") format("woff2");
  font-weight: 1 1000;
  font-style: normal;
  font-display: swap;
  unicode-range: U+2011, U+202F;
}
@font-face {
  font-family: "cpon Hebrew Display";
  src: url("/fonts/cponHebrewDisplay.woff2") format("woff2");
  font-weight: 500 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}
@font-face {
  font-family: "cpon Hebrew Text";
  src: url("/fonts/cponHebrewText.woff2") format("woff2");
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}
@font-face {
  font-family: "cpon Currency Display";
  src: url("/fonts/cponCurrencyDisplay-700.woff2") format("woff2");
  font-weight: 1 749;
  font-style: normal;
  font-display: swap;
  unicode-range: U+20AA, U+20BA;
}
@font-face {
  font-family: "cpon Currency Display";
  src: url("/fonts/cponCurrencyDisplay-800.woff2") format("woff2");
  font-weight: 750 849;
  font-style: normal;
  font-display: swap;
  unicode-range: U+20AA, U+20BA;
}
@font-face {
  font-family: "cpon Currency Display";
  src: url("/fonts/cponCurrencyDisplay-900.woff2") format("woff2");
  font-weight: 850 1000;
  font-style: normal;
  font-display: swap;
  unicode-range: U+20AA, U+20BA;
}
@font-face {
  font-family: "cpon Currency Text";
  src: url("/fonts/cponCurrencyText-400.woff2") format("woff2");
  font-weight: 100 449;
  font-style: normal;
  font-display: swap;
  unicode-range: U+20AA, U+20BA;
}
@font-face {
  font-family: "cpon Currency Text";
  src: url("/fonts/cponCurrencyText-500.woff2") format("woff2");
  font-weight: 450 549;
  font-style: normal;
  font-display: swap;
  unicode-range: U+20AA, U+20BA;
}
@font-face {
  font-family: "cpon Currency Text";
  src: url("/fonts/cponCurrencyText-600.woff2") format("woff2");
  font-weight: 550 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+20AA, U+20BA;
}

:root {
  --ink: #17120F;
  --ink-2: #2A2420;
  --paper: #F7F2EA;
  --card: #FFFDF9;
  --accent: #FC501F;
  --accent-deep: #BF2D0A;
  --accent-soft: #FFE4DA;
  --grey-7: #5E564F;
  --grey-6: #7A6F66;
  --grey-5: #8A7F75;
  --grey-3: #D9D1C7;
  --grey-2: #EDE6DC;
  --display: "Sofia Sans Condensed", "cpon Currency Display", "cpon Hebrew Display", "Arial Narrow", "Helvetica Neue", Arial, sans-serif;
  --text: "Hanken Grotesk", "cpon Currency Text", "Sofia Sans", "cpon Hebrew Text", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  --radius: 20px;
  --tilt: -4deg;
  --stamp-origin: left center;
  --ground: var(--paper);
  --shadow: 0 24px 60px -24px rgba(23, 18, 15, .45), 0 2px 6px -2px rgba(23, 18, 15, .2);
  color-scheme: light;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-bottom: 96px; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--text);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
body { min-height: 100vh; display: flex; flex-direction: column; }
.foot { margin-top: auto; }
img, svg { display: block; }
img { max-width: 100%; height: auto; }
a { color: inherit; }
p { margin: 0 0 1em; }
h1, h2, h3 { margin: 0; font-family: var(--display); font-weight: 800; line-height: 1.02; letter-spacing: -.01em; }
button, input { font: inherit; color: inherit; }
:root { --ring: var(--ink); }
:focus-visible { outline: 3px solid var(--ring); outline-offset: 3px; }
.band--ink, .foot, .sticky { --ring: var(--paper); }
.cpn { --ring: var(--ink); }
.vh { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

.wrap { width: min(100% - 32px, 1200px); margin-inline: auto; }
.wrap--narrow { width: min(100% - 32px, 720px); margin-inline: auto; }

/* receipt type: the tracked condensed capitals of the small print */
.rcpt {
  font-family: var(--display);
  font-weight: 600;
  font-size: 14px;
  letter-spacing: .08em;
  text-transform: uppercase;
  line-height: 1.3;
  color: var(--grey-7);
}
.rcpt--ink { color: var(--ink); }
.kicker { font-weight: 600; font-size: 15px; line-height: 1.3; color: var(--accent-deep); margin: 0 0 10px; }
.band .kicker { color: var(--ink); }
.band--ink .kicker { color: var(--grey-3); }
.num { font-variant-numeric: tabular-nums; }

/* the lock up */
.logo { display: inline-flex; align-items: center; gap: 10px; padding: 7px 0; text-decoration: none; color: inherit; }
.logo svg { height: 32px; width: auto; }
.logo--large svg { height: 44px; }
.logo .mark { color: var(--accent); }
.logo .word { color: var(--ink); }
.band .logo .mark, .band .logo .word { color: var(--ink); }
.band--ink .logo .mark, .foot .logo .mark { color: var(--accent); }
.band--ink .logo .word, .foot .logo .word { color: var(--paper); }

/* the bands */
.band { --ground: var(--accent); background: var(--accent); color: var(--ink); }
.band--ink { --ground: var(--ink); background: var(--ink); color: var(--paper); }
.top { position: relative; z-index: 2; display: flex; align-items: center; justify-content: space-between; min-height: 52px; padding: 2px 0; }
.top__link { font-weight: 600; font-size: 16px; text-decoration: none; padding: 12px 0; }
.top__link:hover { text-decoration: underline; text-underline-offset: 4px; }
@media (min-width: 900px) { .top { min-height: 64px; padding: 8px 0; } }

/* the hero of the coupon page */
.hero { padding: 2px 0 8px; }
.hero h1 { font-size: clamp(36px, 3vw + 26px, 60px); font-weight: 900; letter-spacing: -.015em; max-width: 14ch; }
.hero__deck { font-size: 17px; line-height: 1.35; max-width: 46ch; margin: 6px 0 0; font-weight: 500; }
.hero__ticket { padding-bottom: 36px; }
@media (min-width: 900px) {
  .hero { padding: 10px 0 30px; }
  .hero h1 { max-width: none; }
  .hero__deck { font-size: 19px; margin-top: 14px; max-width: none; }
  .hero__ticket { padding-bottom: 48px; }
}

/* the coupon (ticket) */
.cpn {
  position: relative;
  background: var(--card);
  color: var(--ink);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  display: grid;
  grid-template-rows: auto auto auto;
}
.cpn__face { padding: 8px 16px 12px; }
.cpn__stub { padding: 12px 16px 14px; }
.cpn__hdr { display: flex; justify-content: space-between; gap: 12px; align-items: baseline; margin-bottom: 8px; }
.cpn__hdr .rcpt { white-space: nowrap; }
/* the phone face: the window spans the face; the name, the sub line and the stamp lie on its vermilion at the left, the device at the right */
.cpn__row { display: grid; grid-template-columns: minmax(0, 1fr) 43.5%; grid-template-rows: auto auto 1fr; align-items: start; }
.window { grid-column: 1 / -1; grid-row: 1 / 4; width: 100%; height: 168px; border-radius: 14px; background: var(--accent); overflow: hidden; }
.window img { width: 100%; height: 100%; object-fit: cover; object-position: 100% 50%; }
.cpn__name { grid-column: 1; grid-row: 1; z-index: 1; font-family: var(--display); font-weight: 800; font-size: 26px; line-height: 1; margin-block: 14px 0; margin-inline: 14px 0; letter-spacing: -.01em; color: var(--ink); }
.cpn__sub { grid-column: 1; grid-row: 2; z-index: 1; font-size: 15px; color: var(--ink); margin-block: 4px 0; margin-inline: 14px 0; line-height: 1.3; }
.cpn__row .stamp { grid-column: 1; grid-row: 3; z-index: 1; align-self: end; margin-block: 10px 14px; margin-inline: 10px 0; padding: 6px 7px 7px; letter-spacing: .02em; --stamp: var(--ink); --stamp-dot: var(--paper); }
@media (max-width: 399px) { .window img { object-position: calc(100% + 12px) 50%; } }
/* from 400 to 539 px the window's height follows its width at the picture's own ratio (16 by 9), so the device is whole at every phone
   width: the 390 px budget's 168 px would cut its top and foot as the window widens (fix round 3, C1 M1) */
@media (min-width: 400px) and (max-width: 539px) { .cpn:not(.cpn--compact) .window { height: auto; aspect-ratio: 1240 / 697; } }
@media (max-width: 359px) {
  .cpn__row { grid-template-rows: auto 1fr auto; }
  .window { grid-row: 1 / 3; height: 150px; }
  .cpn__name { font-size: 24px; }
  .cpn__row .stamp { grid-column: 1 / -1; grid-row: 3; align-self: start; margin-block: 14px 0; margin-inline: 2px 0; padding: 6px 10px 7px; letter-spacing: .06em; --stamp: var(--accent-deep); --stamp-dot: var(--accent); }
  .cpn__value { grid-row: 4; }
  .was { grid-row: 5; }
}
.cpn__value { grid-column: 1 / -1; grid-row: 4; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 10px; }
.value { font-family: var(--display); font-weight: 900; font-size: 52px; line-height: .9; letter-spacing: -.02em; font-variant-numeric: tabular-nums; margin: 0; }
.was { grid-column: 1 / -1; grid-row: 5; margin: 4px 0 0; font-size: 15px; color: var(--grey-7); line-height: 1.3; }
.was s { font-family: var(--display); font-size: 1.45em; font-weight: 700; line-height: 1; letter-spacing: -.01em; font-variant-numeric: tabular-nums; text-decoration: line-through; text-decoration-color: var(--accent); text-decoration-thickness: 2px; color: var(--ink); }
.pill { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; border-radius: 999px; font-family: var(--display); font-weight: 700; font-size: 14px; letter-spacing: .06em; text-transform: uppercase; white-space: nowrap; }
.pill--hot { background: var(--accent); color: var(--ink); }
.pill--neutral { background: var(--card); color: var(--grey-7); border: 1px solid var(--grey-3); }

/* the stamp: the price check, coloured by its ground (ink on the vermilion window, vermilion deep on the card) */
.stamp {
  --stamp: var(--accent-deep);
  --stamp-dot: var(--accent);
  display: inline-grid;
  gap: 2px;
  justify-self: start;
  margin: 12px 0 0;
  padding: 6px 10px 7px;
  border: 2px solid var(--stamp);
  outline: 1px solid var(--stamp);
  outline-offset: 2px;
  border-radius: 8px;
  color: var(--stamp);
  font-family: var(--display);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: .06em;
  text-transform: uppercase;
  line-height: 1.15;
  white-space: nowrap;
  transform: rotate(var(--tilt));
  transform-origin: var(--stamp-origin);
  font-variant-numeric: tabular-nums;
}
.stamp__line { display: flex; align-items: center; gap: 7px; }
.stamp__dot { width: 9px; height: 9px; border-radius: 50%; background: var(--stamp-dot, var(--accent)); flex: none; }
.js .stamp { animation: land 240ms cubic-bezier(.2, .9, .3, 1.2) both; }
.js .is-live .stamp__dot { animation: pulse 2s ease-in-out infinite; }
@keyframes land { from { transform: rotate(var(--tilt)) scale(1.08); opacity: .6; } to { transform: rotate(var(--tilt)) scale(1); opacity: 1; } }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
.check { display: inline-flex; align-items: center; gap: 8px; margin: 6px 0 0; font-family: var(--display); font-weight: 700; font-size: 15px; letter-spacing: .06em; text-transform: uppercase; color: var(--accent-deep); line-height: 1.3; font-variant-numeric: tabular-nums; }

/* the tear: the cut line with its notches */
.cpn__tear { position: relative; height: 0; margin: 0 16px; border-top: 2px dashed var(--grey-3); }
.cpn__tear::before, .cpn__tear::after { content: ""; position: absolute; top: -14px; width: 28px; height: 28px; border-radius: 50%; background: var(--ground); }
.cpn__tear::before { inset-inline-start: -30px; }
.cpn__tear::after { inset-inline-end: -30px; }

/* the claim */
.claim__title { display: none; font-family: var(--display); font-weight: 800; font-size: 24px; line-height: 1.05; margin: 0 0 12px; }
.claim__title--home { display: block; }
.field-label { display: block; margin: 0 0 5px; font-weight: 600; font-size: 15px; line-height: 1.3; color: var(--ink); }
.field {
  display: block; width: 100%; height: 56px; padding: 0 16px;
  border: 2px solid var(--ink); border-radius: 12px; background: var(--card);
  font-size: 17px; font-family: var(--text); color: var(--ink);
}
.field::placeholder { color: var(--grey-6); opacity: 1; }
.field:focus { outline: 3px solid var(--accent); outline-offset: 2px; }
.field[aria-invalid="true"] { border-color: var(--accent-deep); }
.field-msg { margin: 0; font-size: 16px; font-weight: 600; line-height: 1.35; color: var(--accent-deep); }
.field-msg:not(:empty) { margin-top: 6px; }
.btn {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; min-height: 58px; margin-top: 10px; padding: 0 18px;
  border: 0; border-radius: 12px; background: var(--ink); color: var(--paper);
  font-family: var(--display); font-weight: 700; font-size: 21px; letter-spacing: .04em; text-transform: uppercase;
  cursor: pointer; text-decoration: none; -webkit-tap-highlight-color: transparent;
}
.btn:hover { background: var(--ink-2); }
.btn:active { transform: translateY(1px); }
.btn[disabled] { cursor: default; opacity: .85; }
.btn__spin { display: none; width: 18px; height: 18px; border: 3px solid rgba(247, 242, 234, .35); border-top-color: var(--paper); border-radius: 50%; }
.btn.is-loading .btn__spin { display: block; animation: spin .8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
/* the consent (RL14): a required opt in between the field and the button (fix round 11: the reading order, the tab order and the DOM
   order are the action order, so the reader meets the box before the act that needs it; under the button was the note's place, L7,
   before RL14 made the line a control). The box is a 24 px card square with the field's 2 px ink rule, ink with the
   icon set's paper tick when ticked, vermilion deep on the soft vermilion when the reader submits without it (aria-invalid from the
   script; :user-invalid from the browser's own check, in the document without the script only, so that with the script on a tick and
   an untick leave the plain square and the colour never comes without the words); the native checkbox lies over it, unpainted, at the
   44 px target, so the focus, the browser's bubble and the tap are the control's own; the operator's line is the label (the whole sentence tappable) with
   the privacy link after it; a live message line sits under the row. The row keeps 12 px above and below it (the button's own 10 px
   collapses into the lower gap): the control reaches 10 px above the row and 34 below its top, the link's 44 px box 11.5 px above and
   below its line, so neither touches the field or the button at one line (23 px) or more */
.consent { position: relative; display: grid; grid-template-columns: 24px minmax(0, 1fr); column-gap: 10px; align-items: start; margin: 12px 0; }
.consent__box { position: absolute; z-index: 1; inset-inline-start: -10px; top: -10px; width: 44px; height: 44px; margin: 0; opacity: 0; cursor: pointer; scroll-margin-top: 140px; }
.consent__tick { grid-column: 1; grid-row: 1; width: 24px; height: 24px; margin-top: -1px; border: 2px solid var(--ink); border-radius: 7px; background: var(--card); color: var(--paper); display: grid; place-items: center; }
.consent__tick svg { width: 18px; height: 18px; opacity: 0; transform: scale(.5); transition: opacity 120ms ease, transform 180ms cubic-bezier(.2, .9, .3, 1.2); }
@media (hover: hover) { .consent__box:hover + .consent__tick { background: var(--grey-2); } }
.consent__box:checked + .consent__tick { background: var(--ink); border-color: var(--ink); }
.consent__box:checked + .consent__tick svg { opacity: 1; transform: none; }
.consent__box:focus-visible + .consent__tick { outline: 3px solid var(--ring); outline-offset: 3px; }
.consent__box[aria-invalid="true"] + .consent__tick { border-color: var(--accent-deep); background: var(--accent-soft); }
html:not(.js) .consent__box:user-invalid + .consent__tick { border-color: var(--accent-deep); background: var(--accent-soft); }
.consent__box[aria-invalid="true"]:focus + .consent__tick { outline: 3px solid var(--accent); outline-offset: 3px; }
html:not(.js) .consent__box:user-invalid:focus + .consent__tick { outline: 3px solid var(--accent); outline-offset: 3px; }
.consent__text { grid-column: 2; grid-row: 1; margin: 0; font-size: 15px; line-height: 1.4; color: var(--grey-7); }
.consent__text label { cursor: pointer; position: relative; }   /* painted over the link's padded box where it reaches the line above: a tap on the sentence always ticks */
.consent__text a { color: var(--accent-deep); display: inline-block; padding: 11.5px 0; margin: -11.5px 0; }   /* a 44 px tall box on a 21 px line */
.consent__text .nobr { white-space: nowrap; }   /* the lead, 2026-10-24: the label breaks between its sentences, never inside the last one */
.consent .field-msg { grid-column: 1 / -1; grid-row: 2; }
.hp { position: absolute; inset-inline-start: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; visibility: hidden; }
.meta { list-style: none; margin: 10px 0 0; padding: 8px 0 0; border-top: 1px solid var(--grey-2); display: grid; gap: 4px; }
.meta li, .meta--line { display: flex; gap: 9px; align-items: flex-start; font-size: 16px; line-height: 1.35; min-height: 22px; color: var(--ink); }
.meta svg { flex: none; width: 20px; height: 20px; color: var(--accent-deep); margin-top: 1px; }
.meta b { font-weight: 600; font-variant-numeric: tabular-nums; }
.decline { margin: 12px 0 0; font-size: 14px; color: var(--grey-7); }
.decline a { color: var(--grey-7); display: inline-block; padding: 13px 0; margin: -13px 0; }

/* the desktop ticket: face left, stub right, a vertical tear; the window the full height of the face, the stamp under the struck price.
   The cut scales with the viewport from 900 to 1100 px (the window 220 to 280, the stub 340 to 440, the side paddings 24 to 32, the
   numeral 66 to 78 px) and is the full cut from 1100: the ticket's minimum content is 832 px at 900, inside the 868 px wrap even beside a
   classic scrollbar, and the face column may shrink (minmax(0, 1fr)), so a wider fallback face can never push the page sideways (fix
   round 3, C3 B1, C1 B1). Under 1220 px the face is the designed stack (the saving pill under the numeral, the struck line capped so the
   store's domain takes its own line); from 1220 the pill sits beside the numeral and the struck line is one line, the width from which
   the face column holds them beside a scrollbar (C1 m4). */
@media (min-width: 900px) {
  .cpn { grid-template-rows: none; grid-template-columns: minmax(0, 1fr) 0 clamp(340px, 340px + (100vw - 900px) * .5, 440px); }
  .cpn__face { padding: 24px clamp(24px, 24px + (100vw - 900px) * .04, 32px) 26px; display: flex; flex-direction: column; }
  .cpn__stub { padding: 26px clamp(24px, 24px + (100vw - 900px) * .04, 32px) 24px; }
  .cpn__hdr { margin-bottom: 18px; }
  .cpn__row { flex: 1; display: flex; flex-direction: column; align-items: flex-start; position: relative; padding-inline-start: clamp(244px, 244px + (100vw - 900px) * .3, 304px); min-height: 290px; }
  .window { position: absolute; inset-inline-start: 0; top: 0; bottom: 0; width: clamp(220px, 220px + (100vw - 900px) * .3, 280px); height: auto; }
  .window img { object-position: 50% 50%; }
  .cpn__name { font-size: 34px; margin: 4px 0 6px; order: 1; }
  .cpn__sub { font-size: 16px; color: var(--grey-7); margin: 0; order: 2; }
  .cpn__value { margin-top: 18px; order: 3; flex-direction: column; align-items: flex-start; gap: 8px; }
  .value { font-size: clamp(66px, 66px + (100vw - 900px) * .06, 78px); }
  .was { font-size: 16px; margin-top: 8px; order: 4; max-width: 250px; }
  .cpn__row .stamp { order: 5; margin: 22px 0 0; align-self: flex-start; padding: 8px 12px 9px; letter-spacing: .06em; --stamp: var(--accent-deep); --stamp-dot: var(--accent); }
  .stamp { font-size: 16px; padding: 8px 12px 9px; }
  .claim__title { display: block; font-size: 26px; }
  .cpn__tear { height: auto; width: 0; margin: 18px 0; border-top: 0; border-inline-start: 2px dashed var(--grey-3); }
  .cpn__tear::before, .cpn__tear::after { inset-inline-start: -15px; inset-inline-end: auto; top: auto; }
  .cpn__tear::before { top: -32px; }
  .cpn__tear::after { bottom: -32px; }
}
@media (min-width: 1220px) {
  .cpn__value { flex-direction: row; align-items: center; gap: 12px; }
  .was { font-size: 17px; max-width: none; }
}
/* the tablet cut, from 540 px (polish round 5: from 540 to 599 the phone window grew 104 to 137 px of flat vermilion between the stamp
   and the device; the square window beside the stack holds from 540, where the stack's column is 238 px) to 899 px */
@media (min-width: 540px) and (max-width: 899px) {
  .cpn__face { padding: 20px 24px 22px; }
  .cpn__stub { padding: 20px 24px 20px; }
  .cpn__tear { margin: 0 24px; }
  .cpn__tear::before { inset-inline-start: -38px; }
  .cpn__tear::after { inset-inline-end: -38px; }
  .cpn__row { grid-template-columns: 200px minmax(0, 1fr); grid-template-rows: auto auto auto auto auto; gap: 0 22px; }
  .window { grid-column: 1; grid-row: 1 / 6; width: 200px; height: auto; align-self: stretch; min-height: 200px; }
  .window img { object-position: 50% 50%; }
  .cpn__name { grid-column: 2; grid-row: 1; font-size: 30px; margin: 4px 0 0; }
  .cpn__sub { grid-column: 2; grid-row: 2; font-size: 15px; color: var(--grey-7); margin: 4px 0 0; }
  .cpn__value { grid-column: 2; grid-row: 3; margin-top: 12px; }
  .value { font-size: 66px; }
  .was { grid-column: 2; grid-row: 4; font-size: 16px; }
  .cpn__row .stamp { grid-column: 2; grid-row: 5; align-self: start; margin: 16px 0 0; font-size: 15px; padding: 6px 10px 7px; letter-spacing: .06em; --stamp: var(--accent-deep); --stamp-dot: var(--accent); }
  .claim__title { display: block; }
}
/* from 760 to 899 px the face has room at the right of the stack (156 px of empty card at 768 and 271 at 899, with only VALID TODAY
   above it): the stamp takes that corner, bottom aligned with the window's foot, and the stack keeps the name, the sub line, the value
   and the struck line; under 760 the three columns would not fit (the stack needs 238 px beside the 200 px window and the 176 px stamp),
   so the stamp stays under the struck line (fix round 6, C1 m2) */
@media (min-width: 760px) and (max-width: 899px) {
  .cpn:not(.cpn--compact) .cpn__row { grid-template-columns: 200px minmax(0, 1fr) auto; grid-template-rows: auto auto auto auto 1fr; }
  .cpn:not(.cpn--compact) .cpn__row .stamp { grid-column: 3; grid-row: 1 / 6; align-self: end; justify-self: end; margin-block: 0 2px; margin-inline: 0 2px; }
}

/* the compact coupon (the repeats): the same object, a small square window beside the name */
.cpn--compact .cpn__row { grid-template-columns: 80px minmax(0, 1fr); grid-template-rows: auto auto auto auto; gap: 0 12px; }
.cpn--compact .window { grid-column: 1; grid-row: 1 / 5; width: 80px; height: 80px; border-radius: 10px; }
.cpn--compact .window img { object-position: 50% 50%; }
.cpn--compact .cpn__name { grid-column: 2; grid-row: 1; font-size: 20px; margin: 0 0 6px; }
.cpn--compact .cpn__value { grid-column: 2; grid-row: 2; margin-top: 0; gap: 10px; }
.cpn--compact .value { font-size: 40px; }
.cpn--compact .was { grid-column: 2; grid-row: 3; margin-top: 4px; font-size: 15px; }
.cpn--compact .check { grid-column: 2; grid-row: 4; }
.cpn--compact .meta--line { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--grey-2); }
@media (min-width: 540px) and (max-width: 899px) {
  .cpn--compact .cpn__row { grid-template-columns: 120px minmax(0, 1fr); gap: 0 22px; }
  .cpn--compact .window { grid-row: 1 / 5; width: 120px; height: 120px; min-height: 0; align-self: start; }
  .cpn--compact .cpn__name { font-size: 24px; }
  .cpn--compact .cpn__value { grid-row: 2; margin-top: 0; }
  .cpn--compact .value { font-size: 48px; }
  .cpn--compact .was { grid-row: 3; font-size: 15px; }
  .cpn--compact .check { grid-row: 4; }
}
@media (min-width: 900px) {
  .cpn--compact .cpn__face { padding: 22px 28px 24px; }
  .cpn--compact .cpn__stub { padding: 22px 28px 22px; }
  .cpn--compact .cpn__row { padding-inline-start: 184px; min-height: 160px; }
  .cpn--compact .window { width: 160px; height: 160px; bottom: auto; }
  .cpn--compact .cpn__name { font-size: 28px; margin: 2px 0 10px; }
  .cpn--compact .cpn__value { margin-top: 0; }
  .cpn--compact .value { font-size: 56px; }
  .cpn--compact .was { font-size: 16px; }
  .cpn--compact .check { font-size: 15px; margin-top: 12px; order: 5; }
  .cpn--compact .claim__title { display: none; }
}

/* the sticky bar on phones */
.sticky {
  position: fixed; inset-inline: 0; bottom: 0; z-index: 20;
  display: none; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
  background: var(--ink); color: var(--paper);
  box-shadow: 0 -8px 30px rgba(23, 18, 15, .25);
}
.sticky__price { font-family: var(--display); font-weight: 800; font-size: 24px; line-height: 1; letter-spacing: -.01em; }
.sticky__sub { display: block; font-size: 14px; line-height: 1.2; color: var(--grey-3); margin-top: 3px; }
.sticky__btn { flex: none; display: inline-flex; align-items: center; justify-content: center; min-height: 48px; padding: 0 20px; border-radius: 10px; background: var(--accent); color: var(--ink); font-family: var(--display); font-weight: 700; font-size: 18px; letter-spacing: .04em; text-transform: uppercase; text-decoration: none; }
.js .sticky { display: flex; }
.js .sticky[hidden] { display: none; }
body:has(.field:focus) .sticky { display: none; }
.js .sticky-on .foot { padding-bottom: 118px; }
@media (min-width: 768px) { .js .sticky { display: none; } .js .sticky-on .foot { padding-bottom: 34px; } }

/* sections */
.sec { padding: 44px 0; }
.sec--tight { padding: 8px 0 28px; }
.sec--live { padding: 24px 0 8px; }
.sec__gap { height: 24px; }
.sec h2 { font-size: clamp(30px, 2vw + 20px, 44px); font-weight: 800; max-width: 22ch; }
.sec__lead { font-size: 18px; max-width: 54ch; margin: 12px 0 0; color: var(--ink); }
.band--ink .sec h2, .band--ink h2 { color: var(--paper); }
.band--ink .sec__lead { color: var(--grey-3); }

/* the facts */
.facts { list-style: none; margin: 26px 0 0; padding: 0; display: grid; gap: 12px; }
.fact { background: var(--card); border-radius: 16px; padding: 18px 18px 16px; border: 1px solid var(--grey-2); }
.fact p.fact__big { font-family: var(--display); font-weight: 900; font-size: 44px; line-height: .95; letter-spacing: -.02em; color: var(--ink); margin: 0; }
.fact__big small { font-size: .5em; font-weight: 700; letter-spacing: 0; margin-inline-start: 3px; }
.fact p { margin: 8px 0 0; font-size: 16px; color: var(--grey-7); line-height: 1.4; }
@media (min-width: 700px) { .facts { grid-template-columns: repeat(3, 1fr); gap: 16px; } .fact { padding: 24px 22px 22px; } .fact p.fact__big { font-size: 56px; } }

/* the pictures */
.shots { display: grid; gap: 14px; margin-top: 26px; }
.shot { background: var(--card); border-radius: 16px; overflow: hidden; border: 1px solid var(--grey-2); margin: 0; }
.shot img { width: 100%; height: auto; }
.shot figcaption { padding: 12px 16px 14px; font-size: 16px; color: var(--grey-7); line-height: 1.4; }
.shot--wide { margin-top: 30px; }
@media (min-width: 700px) { .shots { grid-template-columns: 3fr 2fr; gap: 16px; align-items: start; } .shot--wide { margin-top: 36px; } }
/* the wide scene is drawn whole at every width, its own shape (run 16's fix round: the 3 by 1.4 band from 900 px cut the device out of 26 of the 131 generated scenes) */

/* the quote, with the review's own photograph beside it */
.review { display: grid; gap: 16px; margin-top: 30px; }
.review__pic { margin: 0; }
.review .quote { margin: 0; align-self: center; }
@media (min-width: 700px) { .review { grid-template-columns: 2fr 3fr; gap: 36px; align-items: center; margin-top: 36px; } }
.quote { margin: 30px 0 0; padding-block: 4px; padding-inline: 18px 0; border-inline-start: 4px solid var(--accent); }
.quote p { font-family: var(--display); font-weight: 700; font-size: clamp(24px, 1.5vw + 16px, 34px); line-height: 1.12; letter-spacing: -.01em; margin: 0; max-width: 24ch; }
.quote footer { margin-top: 10px; font-size: 14px; color: var(--grey-7); }

/* the objections */
.qa { display: grid; gap: 22px; margin-top: 26px; }
.qa h3 { font-size: 22px; font-weight: 800; margin-bottom: 6px; }
.qa p { margin: 0; color: var(--ink); max-width: 46ch; }
@media (min-width: 700px) { .qa { grid-template-columns: 1fr 1fr; gap: 28px 40px; } }

/* the fine print */
.fine { padding: 26px 0 30px; border-top: 1px solid var(--grey-3); }
.fine p { font-size: 14px; color: var(--grey-7); margin: 0 0 6px; max-width: 70ch; }
.fine a { color: var(--grey-7); display: inline-block; padding: 13px 4px; margin: -13px 0; }

/* the footer */
.foot { --ground: var(--ink); background: var(--ink); color: var(--paper); padding: 30px 0 34px; border-top: 1px solid rgba(247, 242, 234, .12); }
.foot__row { display: flex; flex-wrap: wrap; gap: 14px 28px; align-items: center; justify-content: space-between; }
.foot__links { display: flex; flex-wrap: wrap; gap: 6px 10px; list-style: none; margin: 0; padding: 0; }
.foot__links a { color: var(--paper); font-family: var(--display); font-weight: 600; font-size: 16px; letter-spacing: .06em; text-transform: uppercase; text-decoration: none; padding: 10px 12px; display: inline-block; }
.foot__links li:first-child a { padding-inline-start: 0; }
.foot__links a:hover { text-decoration: underline; text-underline-offset: 4px; }
.foot__pub { margin: 14px 0 0; font-size: 14px; color: var(--grey-3); }

/* the homepage hero: the search at the left, the device on its vermilion at the right */
.band--home { position: relative; }
.home-hero { padding: 12px 0 0; }
.home-hero__text { position: relative; z-index: 3; max-width: 720px; padding-bottom: 28px; }
.home-hero h1 { font-size: clamp(40px, 4vw + 22px, 76px); font-weight: 900; letter-spacing: -.02em; max-width: 12ch; }
.home-hero__deck { font-size: 17px; font-weight: 500; max-width: 46ch; margin: 10px 0 18px; line-height: 1.4; }
.home-hero__pic { display: none; position: absolute; inset: 0; margin: 0; overflow: hidden; }
.home-hero__pic img { width: 100%; height: 100%; object-fit: contain; object-position: 100% 50%; -webkit-mask-image: linear-gradient(to right, transparent, #000 30%); mask-image: linear-gradient(to right, transparent, #000 30%); }
@media (min-width: 700px) and (max-width: 899px) {
  .home-hero { min-height: 400px; padding-top: 16px; }
  .home-hero__text { max-width: 53%; padding-bottom: 36px; }
  .home-hero__pic { display: block; }
}
@media (min-width: 900px) {
  .home-hero { min-height: 500px; padding-top: 24px; }
  .home-hero__text { padding-bottom: 48px; }
  .home-hero__deck { font-size: 19px; margin: 16px 0 26px; }
  .home-hero__pic { display: block; }
}
/* from 900 to 1199 px the text column is 55 percent of the wrap at 900, growing to 60 at 1199: the search box ends 31 px before the
   hero device's plug end at 900 and the air grows with the width (polish round 5; at 60 percent the plug end sat inside the box to 930) */
@media (min-width: 900px) and (max-width: 1199px) { .home-hero__text { max-width: calc(55% + (100vw - 900px) * .19); } }
.search { position: relative; max-width: 720px; }
.search__box { display: flex; align-items: center; height: 64px; padding-block: 0; padding-inline: 16px 6px; background: var(--card); border: 2px solid var(--ink); border-radius: 14px; box-shadow: var(--shadow); }
.search__box svg { flex: none; width: 22px; height: 22px; color: var(--grey-7); }
.search__input { flex: 1; min-width: 0; height: 100%; border: 0; background: transparent; padding: 0 12px; font-size: 18px; color: var(--ink); }
.search__input::placeholder { color: var(--grey-6); opacity: 1; }
.search__input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; flex: none; width: 16px; height: 16px; margin-block: 0; margin-inline: 6px 2px; cursor: pointer; background: var(--grey-7); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M6 6l12 12M18 6L6 18'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M6 6l12 12M18 6L6 18'/%3E%3C/svg%3E") center / contain no-repeat; }
.search__input:focus { outline: none; }
.search__box:focus-within { outline: 3px solid var(--ink); outline-offset: 3px; }
.search__btn { flex: none; height: 48px; padding: 0 18px; border: 0; border-radius: 10px; background: var(--ink); color: var(--paper); font-family: var(--display); font-weight: 700; font-size: 18px; letter-spacing: .04em; text-transform: uppercase; cursor: pointer; }
.search__btn:hover { background: var(--ink-2); }
.results { position: absolute; inset-inline: 0; top: calc(100% + 8px); z-index: 10; margin: 0; padding: 6px; list-style: none; background: var(--card); color: var(--ink); border-radius: 14px; box-shadow: var(--shadow); border: 1px solid var(--grey-2); }
.results[hidden] { display: none; }
.results li { border-radius: 10px; }
.results a, .results span.row { display: flex; align-items: center; gap: 12px; min-height: 48px; padding: 6px 10px; text-decoration: none; color: var(--ink); border-radius: 10px; }
.results a:hover, .results li.is-top a { background: var(--grey-2); }
.results .row__name { font-family: var(--display); font-weight: 700; font-size: 18px; }
.results .row__cat { font-size: 14px; color: var(--grey-7); margin-inline-start: auto; text-align: end; }
.results .row__note { padding: 10px 10px; font-size: 15px; color: var(--grey-7); }
@media (max-width: 599px) {
  .results a, .results span.row { flex-wrap: wrap; row-gap: 2px; }
  .results .row__cat { flex-basis: 100%; margin-inline-start: 0; text-align: start; }
}
.search__hint { margin: 10px 0 0; font-size: 16px; color: var(--ink); }
@media (max-width: 359px) { .search__btn { padding: 0 12px; } .search__input { padding: 0 8px; } }
.search__hint a { color: var(--ink); font-weight: 600; display: inline-block; padding: 12px 0; margin: -12px 0; }

/* the homepage ticket: the same object, a button where the form is */
.cpn--home .cpn__stub .btn { margin-top: 0; }
.cpn--home .claim__title { font-size: 22px; margin-bottom: 10px; }
@media (min-width: 900px) { .cpn--home .claim__title { font-size: 26px; } .cpn--home .cpn__stub { display: flex; flex-direction: column; justify-content: center; } }

/* the brand tiles: miniature coupons */
.tiles { list-style: none; margin: 24px 0 0; padding: 0; display: grid; gap: 14px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.tile { --ground: var(--paper); position: relative; display: grid; grid-template-rows: auto auto 1fr; background: var(--card); border-radius: 16px; box-shadow: 0 10px 30px -18px rgba(23, 18, 15, .4); border: 1px solid var(--grey-2); color: var(--ink); text-decoration: none; }
.tile__pic { background: #fff; border-radius: 16px 16px 0 0; padding: 8px; }
.tile__pic img { width: 100%; height: auto; aspect-ratio: 1; object-fit: contain; }
.tile__tear { position: relative; height: 0; margin: 0 12px; border-top: 2px dashed var(--grey-3); }
.tile__tear::before, .tile__tear::after { content: ""; position: absolute; top: -10px; width: 20px; height: 20px; border-radius: 50%; background: var(--ground); border: 1px solid var(--grey-2); }
.tile__tear::before { inset-inline-start: -23px; border-inline-end-color: transparent; }
.tile__tear::after { inset-inline-end: -23px; border-inline-start-color: transparent; }
.tile__stub { padding: 10px 12px 12px; display: grid; gap: 3px; align-content: start; }
.tile__name { font-family: var(--display); font-weight: 800; font-size: 20px; line-height: 1.05; }
.tile__cat { font-size: 14px; color: var(--grey-7); line-height: 1.3; }
.tile__status { margin-top: 5px; }
.tile--live { border-color: var(--ink); box-shadow: var(--shadow); }
.tile--live .tile__name { font-size: 22px; }
a.tile:hover { transform: translateY(-2px); }
a.tile:hover .tile__pic img { transform: scale(1.03); }
.tile__pic img, a.tile { transition: transform 160ms ease; }
.tile--live .tile__pic { background: var(--accent); }
.tiles > li:first-child { grid-column: span 2; }
.tiles > li > .tile { height: 100%; }
.tile--live .tile__pic img { aspect-ratio: 2 / 1; }
@media (min-width: 900px) and (max-width: 1199px) { .tiles > li:first-child { grid-row: span 2; } .tile--live .tile__pic img { aspect-ratio: 1; } }
.tiles__more { display: none; width: 100%; min-height: 54px; margin-top: 14px; padding: 0 18px; border: 2px solid var(--ink); border-radius: 12px; background: var(--card); color: var(--ink); font-family: var(--display); font-weight: 700; font-size: 18px; letter-spacing: .04em; text-transform: uppercase; cursor: pointer; }
.tiles__more:hover { background: var(--grey-2); }
@media (max-width: 559px) { .js .tiles--folded li:nth-child(n+8) { display: none; } .js .tiles--folded + .tiles__more:not([hidden]) { display: block; } }
@media (min-width: 560px) { .tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; } }
@media (min-width: 900px) { .tiles { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 18px; } }
@media (min-width: 1200px) { .tiles { grid-template-columns: repeat(6, minmax(0, 1fr)); } }

/* how it works: the ink band with the tickets still life */
.how { padding: 48px 0 52px; }
.how__grid { display: grid; gap: 30px; }
.how h2 { font-size: clamp(30px, 2vw + 20px, 44px); max-width: 22ch; }
.steps { list-style: none; margin: 24px 0 0; padding: 0; display: grid; gap: 18px; }
.step { display: grid; grid-template-columns: 52px 1fr; gap: 12px; align-items: start; }
.step__n { font-family: var(--display); font-weight: 900; font-size: 40px; line-height: .9; color: var(--accent); letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.step h3 { font-size: 22px; margin-bottom: 4px; color: var(--paper); }
.step p { margin: 0; color: var(--grey-3); }
.about { margin: 28px 0 0; font-size: 17px; max-width: 46ch; color: var(--grey-3); }
.how__pic img { width: 100%; height: auto; border-radius: 16px; }
@media (min-width: 900px) {
  .how { padding: 64px 0 68px; }
  .how__grid { grid-template-columns: 1fr 1fr; gap: 56px; align-items: center; }
  .steps { gap: 22px; margin-top: 28px; }
  .step__n { font-size: 48px; }
}

/* the legal pages and the 404 */
.page-head { padding: 10px 0 34px; }
.page-head h1 { font-size: clamp(36px, 3vw + 22px, 60px); font-weight: 900; letter-spacing: -.015em; max-width: 16ch; }
.page-head p { font-size: 18px; font-weight: 500; margin: 12px 0 0; max-width: 46ch; }
.prose { padding: 36px 0 48px; font-size: 17px; line-height: 1.6; }
.prose h2 { font-size: 26px; margin: 30px 0 8px; }
.prose p, .prose li { max-width: 68ch; }
.prose ul { padding-inline-start: 20px; }
.prose a { color: var(--accent-deep); display: inline-block; padding: 11px 0; margin: -11px 0; }
.prose .kicker { margin-top: 24px; }
.card { background: var(--card); border: 1px solid var(--grey-2); border-radius: 16px; padding: 18px 20px; margin: 10px 0 20px; }
.card p { margin: 0 0 4px; }
.pills-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.btn--inline { display: inline-flex; width: auto; min-height: 54px; padding: 0 22px; margin: 0; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .stamp, .js .is-live .stamp__dot, .btn.is-loading .btn__spin, .tile__pic img, a.tile, .consent__tick svg { animation: none; transition: none; }
  a.tile:hover { transform: none; }
  a.tile:hover .tile__pic img { transform: none; }
}

/* STAGE 2: the store window. A brand whose picture is the official store's own render (a product on its white studio ground) shows
   it in a white photo cell mounted inside the vermilion window, so the ticket keeps its vermilion label on the phone face (the name,
   the sub line and the stamp on the flat vermilion at the inline start, the photo at the inline end, as the XtraBoost window set it)
   and the render is never cut; from 540 px the cell fills the square window inside an 8 px vermilion frame. The identity window
   (XtraBoost's generated picture on the identity's ground) keeps the plain .window. */
@media (max-width: 899px) { .window--store { position: relative; } }   /* from 900 px the window is absolute already (the desktop face) */
/* fix round 10 (C1B m1, C3B m2, C2B m2): the cell stands 6 px off the text column (the gutter), so a name or a sub line that fills its column
   never meets the white card (0.4 px on AltaSSD's and CarFixio's subs at 390 before); the text column keeps its width, so no line wraps
   anew and nothing under the window moves; the picture inside is 6 px narrower (STORE_SIZES in gen.py follows) */
.window__pic { position: absolute; inset-block: 8px; inset-inline-end: 8px; width: calc(43.5% - 14px); padding: 6px; background: #fff; border-radius: 10px; overflow: hidden; }
.window--store img { width: 100%; height: 100%; object-fit: contain; object-position: 50% 50%; }
@media (max-width: 359px) { .window__pic { inset-block: 6px; inset-inline-end: 6px; width: calc(43.5% - 12px); padding: 4px; } }
/* from 540 px the window is the photo alone: the cell fills it on white with the tiles' hairline (the identity's own grammar for a
   store render), no vermilion frame; the compact window the same at every width */
@media (min-width: 540px) { .window--store { background: #fff; border: 1px solid var(--grey-2); } .window__pic { inset: 0; width: auto; padding: 10px; border-radius: 0; } }
.cpn--compact .window--store { background: #fff; border: 1px solid var(--grey-2); }
.cpn--compact .window__pic { inset: 0; width: auto; padding: 4px; border-radius: 0; }
@media (min-width: 540px) { .cpn--compact .window__pic { padding: 6px; } }

/* STAGE 2: every tile is a link to a live coupon; the top brand's tile keeps the vermilion window and the ink border (.tile--live).
   A tile's pill may wrap when it must: a four digit figure with its symbol ("₺1349.99 coupon", "31 491 Ft coupon") is wider than a
   137 px tile at 320 px and an unbreakable pill pushed the page 2 px sideways (the TR battery); a pill that fits is unchanged (the
   28 px minimum height, the same padding), one that does not takes two lines inside its badge. */
a.tile { cursor: pointer; }
.tile .pill { white-space: normal; height: auto; min-height: 28px; padding: 4px 10px; line-height: 1.2; text-align: center; }
/* FIX ROUND 9 (C1, C2 and C3 round 9 B1; RL26 c): since fix round 8 the pill's figure is a span (span.pr, never broken inside), so the pill
   is a flex row of two items, the figure and the word, and white-space alone cannot put the word under the figure: the pill's narrowest
   width was the whole line, the tile's column took it and the stub, the tear and the pill ran up to 25 px past the card in nine currencies
   (the homepage scrolled sideways at 320 to 360 px). The two items wrap now, centred, with no gap between the lines (the hero's saving pill
   does the same): a long print ("kr13499.10", "35 999 Ft") takes the figure over "coupon" inside its badge; a pill that fits keeps one line.
   The stage 1 narrow rule follows it, so it applies (before, the stage 2 rules overrode it by their place): under 360 px the stub's sides
   are 10 px and the pill's 8 px with .04em tracking, and a euro pill keeps its one line at 320. */
.tile .pill { flex-wrap: wrap; justify-content: center; row-gap: 0; }
@media (max-width: 359px) { .tile__stub { padding: 10px 10px 12px; } .tile .pill { padding-inline: 8px; letter-spacing: .04em; } }
/* STAGE 2B (RL37): a brand whose window is its generated pair (the device photographed on the identity's vermilion, as XtraBoost's) shows
   its tile as XtraBoost's tile has it: the square on the vermilion picture area; the white area of a store render's tile goes */
.tile--ground .tile__pic { background: var(--accent); }
/* STAGE 2B FIX ROUND 1 (C1 s2b-r1 m1, C2 s2b-r1 m16): the generated tile's square is drawn to its picture area's edges. XtraBoost's 8 px
   accent ring stopped the three cords that leave their square (AXEG Pro Mouse's at the top, AeroLusso's and HeatBliss's at the foot) dead
   8 px inside the vermilion, and it read as a faint frame round a square whose own ground lies more than 3 dE76 from the accent (17 of the
   131); the square's own ground is the area now, clipped by the area's rounded top corners (the hover's zoom inside it) */
.tile--ground .tile__pic { padding: 0; overflow: hidden; }
/* STAGE 2B: the generated window (window--gen) keeps XtraBoost's plain window and adds its picture's own ground where the picture leaves
   the window's background in view: under 400 px the 12 px shift uncovers 1 to 12 px at the inline start (--wl, the wide cut's left edge);
   from 540 px a pair whose device is wider than the tallest window shows under cover (window--fit, set by the generator from the device's
   box: the face stands up to 1.64 times as tall as the window is wide) shows the whole square on its own top and bottom edge colours (--wt,
   --wb), so no device is cut and no band reads as a band; the colours are measured from the picture by pictures.py generated_set */
.window--gen { background: var(--wl, var(--accent)); }
@media (min-width: 540px) {
  .window--gen { background: linear-gradient(var(--wt, var(--accent)) 50%, var(--wb, var(--accent)) 50%); }
  .window--fit img { object-fit: contain; }
}
/* from 360 to 399 px the generated window grows with its words as the store window does (a two line name over a two line sub line put
   SkyScout's three line stamp past the 168 px window's foot); its picture lies under them, absolutely, so it never sets the height. Run 15:
   the picture keeps its own size there (the window's width at the wide cut's 1240 by 697), centred on the window's height, never scaled up
   by a grown window (cover scaled SkyScout's monocular 1.24 times at 360 px and brought it under the stamp's live words); a taller window
   shows its ground (--wl) above and below the picture, a shorter one crops the picture evenly at the top and the foot as cover did */
@media (min-width: 360px) and (max-width: 399px) {
  .cpn:not(.cpn--compact) .window--gen { position: relative; height: auto; min-height: 168px; align-self: stretch; }
  .cpn:not(.cpn--compact) .window--gen img { position: absolute; inset: auto 0; top: 50%; height: auto; aspect-ratio: 1240 / 697; transform: translateY(-50%); }
}
/* RUN 15: the facts row goes three across from 768 px. From 700 px its three columns of 1fr were each at least as wide as their content, so
   a long word in a big figure ("Rechargeable", "Adjustable", "Breathable") made the row wider than the page from 700 to 740 px (FalconTorch,
   SpineBuzz, SilkyCloud: a side scroll, since stage 2); under 768 px the row keeps the phone's single column, the cards their tablet type */
@media (min-width: 700px) and (max-width: 767px) { .facts { grid-template-columns: none; } }

/* STAGE 2: the mirrored page (dir="rtl", Hebrew in stage 3). The logical properties above mirror the layout by themselves; what a
   photograph cannot mirror is set here: the identity window's picture keeps the device at the right (its own composition), so its
   label moves to the other column; the store window mirrors whole. Prices, clocks and the brand names read left to right inside the
   mirrored line. */
[dir="rtl"] { --tilt: 4deg; --stamp-origin: right center; }
[dir="rtl"] .window--store img { object-position: 50% 50%; }
[dir="rtl"] :where(.cpn:not(.cpn--compact)) .cpn__row--identity { grid-template-columns: 43.5% minmax(0, 1fr); }
[dir="rtl"] :where(.cpn:not(.cpn--compact)) .cpn__row--identity > .cpn__name, [dir="rtl"] :where(.cpn:not(.cpn--compact)) .cpn__row--identity > .cpn__sub, [dir="rtl"] :where(.cpn:not(.cpn--compact)) .cpn__row--identity > .stamp { grid-column: 2; }
@media (max-width: 359px) { [dir="rtl"] :where(.cpn:not(.cpn--compact)) .cpn__row--identity > .stamp { grid-column: 1 / -1; } }
[dir="rtl"] .home-hero__pic img { position: absolute; top: 0; inset-inline-end: 0; width: auto; max-width: none; height: 100%; transform: translateX(-47%); -webkit-mask-image: linear-gradient(to left, transparent, #000 6%); mask-image: linear-gradient(to left, transparent, #000 6%); }
[dir="rtl"] .field { direction: ltr; text-align: end; }
/* STAGE 3 (EXTEND-PLAN W14): the hero text keeps its own start (the right) on a mirrored homepage (an auto start margin pushed it onto the
   device from 700 px); a price print, a clock and a Latin name read left to right inside a right to left line, isolated (every composed
   line's print is a span.pr, the search rows' names too; the generator also isolates every filled token with U+2068 and U+2069); a fact
   card's figure sits in a bdi on a right to left page (300 Mbps left to right, a Hebrew figure right to left, the card's start edge kept) */
[dir="rtl"] .value, [dir="rtl"] .was s, [dir="rtl"] .num, [dir="rtl"] .sticky__price, [dir="rtl"] .pr, [dir="rtl"] .cpn__name, [dir="rtl"] .tile__name, [dir="rtl"] .row__name { direction: ltr; unicode-bidi: isolate; }

/* STAGE 2 ASSEMBLY: a review block without a picture (the fleet's review quoted, its pictures not fetched: fifteen brands) spans the grid,
   so the second column never stands empty from 700 px; the quote keeps its 24ch measure. */
@media (min-width: 700px) { .review--quote { grid-template-columns: minmax(0, 1fr); } }

/* STAGE 2 ASSEMBLY: the tile wall folds at every width, not only on phones: 133 live tiles would stand 23 rows deep at 1200 px and 45 at
   560 px, under the search that finds a brand in one keystroke. Seven tiles show under 560 px as before (the top tile's row and three
   rows of two), fourteen to 899 (three columns: the top tile with one beside it, then four rows of three), seventeen to 1199 (four
   columns, the top tile two by two: two rows of the top tile and two, then three rows of four), twenty nine from 1200 (six columns: the
   top tile with four beside it, then four rows of six): five full rows at every grid, no ragged last row; the rest wait behind "Show all
   N brands", which the script shows at every width; without the script every tile stands. */
.js .tiles--folded + .tiles__more:not([hidden]) { display: block; }
@media (min-width: 560px) and (max-width: 899px) { .js .tiles--folded li:nth-child(n+15) { display: none; } }
@media (min-width: 900px) and (max-width: 1199px) { .js .tiles--folded li:nth-child(n+18) { display: none; } }
@media (min-width: 1200px) { .js .tiles--folded li:nth-child(n+30) { display: none; } }

/* STAGE 2 ASSEMBLY (RL20): the exclusivity line. The operator's fact (FACTS.md, Exclusivity: the cpon price is found nowhere else, not in
   the official store, not on any other site) stands on every coupon page as the value's third attribute, after the price and the saving
   and before the struck store line: "Found nowhere else." (ui/en.json coupon.exclusive) in ink at 15 px 600, one line, on the hero coupon
   only. It is a flex item of the value row that takes its own line under the numeral and the pill; the row's gap (12 px on the phone, 8 in
   the desktop column, 12 in the desktop row) is drawn back above it to 2 px on the phone and 4 px from 540 px, so the first phone screen
   at 390 by 844 keeps the whole offer (fold-all.mjs: the meta list ends at 841, 821 before; the button 669 to 727). It is sized by its
   width, not its flex basis: from 900 to 1219 px the value row is a column, where a basis of 100% is a height and a wrapped item starts
   a second column beside the numeral (build a6 at 1024 painted the line across the tear into the stub). */
.only { flex: 0 0 auto; width: 100%; margin: -10px 0 0; font-size: 15px; font-weight: 600; line-height: 1.2; color: var(--ink); }
@media (min-width: 540px) { .only { margin-top: -8px; } }
@media (min-width: 900px) { .only { margin-top: -4px; font-size: 16px; } }
@media (min-width: 1220px) { .only { margin-top: -8px; } }

/* FIX ROUND 8: the first phone screen holds the whole offer in every currency (the critics' round 8, C1 M3 and C2 m7: at 390 by 844 the
   four digit lira prices pushed the saving pill under the 52 px numeral, the ticket grew 40 px and the meta list fell under the fold; the
   same wrap by the print lengths in forints, koruna, krona and shekels). Three rules at the cause, and no geometry change in euros:
   (a) from 360 to 539 px the value row is a grid of two columns, the numeral and the pill's cell, so a pill that does not fit beside the
   numeral wraps its words inside its badge ("YOU SAVE" over the figure, two lines of 14 px inside the numeral's 46.8 px line box) instead
   of dropping under the numeral; a pill that fits is unchanged; the exclusivity line spans both columns under them as before;
   (b) the numeral's size follows its print's length where the face is narrow (data-n, the character count the PHP and the render both
   write: 8 for ₺1349.99, 9 for 14 849 Ft or Kč1124.99, 10 for kr13589.99), with its line box kept at the 52 px size's 46.8 px on the phone
   so the ticket's height is the same for every currency, and smaller steps on the tablet and in the desktop column, where the stack is
   236 to 299 px wide; under 360 px the row keeps its flex wrap (the pill under the numeral in euros too) and the compact coupon keeps
   its own flex wrap at every width (the pill under its 40 px numeral in euros too); (c) a price print never breaks inside itself: the
   numeral and the sticky bar's price by white-space, every composed line's print (the h1, the deck, the stamp, the pill, the button, the
   heading, the decline, the tile pill) inside span.pr, which also keeps the store's own case on zł, kr, Lei and Ft inside the uppercase
   lines (C4 m8). */
.value, .sticky__price { white-space: nowrap; }
.pr { white-space: nowrap; text-transform: none; }
@media (min-width: 360px) and (max-width: 539px) {
  .cpn:not(.cpn--compact) .cpn__value { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 12px; row-gap: 0; align-items: center; }
  .cpn:not(.cpn--compact) .cpn__value > .value { grid-column: 1; }
  .cpn:not(.cpn--compact) .cpn__value > .pill { grid-column: 2; justify-self: start; flex-wrap: wrap; justify-content: center; row-gap: 0; height: auto; min-height: 28px; padding: 4px 10px; line-height: 1.2; text-align: center; }
  .cpn:not(.cpn--compact) .cpn__value > .only { grid-column: 1 / -1; margin-top: 2px; }
}
@media (max-width: 539px) {
  .cpn:not(.cpn--compact) .value[data-n="8"] { font-size: 48px; line-height: .975; }
  .cpn:not(.cpn--compact) .value[data-n="9"] { font-size: 44px; line-height: 1.0636; }
  .cpn:not(.cpn--compact) .value[data-n="10"], .cpn:not(.cpn--compact) .value[data-n="11"], .cpn:not(.cpn--compact) .value[data-n="12"] { font-size: 40px; line-height: 1.17; }
}
@media (max-width: 359px) {
  .cpn--compact .value[data-n="9"] { font-size: 36px; line-height: 1; }
  .cpn--compact .value[data-n="10"], .cpn--compact .value[data-n="11"], .cpn--compact .value[data-n="12"] { font-size: 34px; line-height: 1.0588; }
}
@media (min-width: 540px) and (max-width: 899px) {
  .cpn:not(.cpn--compact) .value[data-n="8"] { font-size: 60px; line-height: .99; }
  .cpn:not(.cpn--compact) .value[data-n="9"] { font-size: 54px; line-height: 1.1; }
  .cpn:not(.cpn--compact) .value[data-n="10"], .cpn:not(.cpn--compact) .value[data-n="11"], .cpn:not(.cpn--compact) .value[data-n="12"] { font-size: 48px; line-height: 1.2375; }
}
/* the hero's struck line from 360 to 379 px: a store print of seven characters and more wrapped "at the official store, techfibrr.com"
   onto a second line (the shekel's seven character print by its sign's width), so the line steps down there, the words at 14 px and the
   figure at 1.3em, for every print alike: the ticket is then the same height in every currency (a step for the long prints only left the
   euro line 4.3 px taller than the lira line); nine character prints and more take the figure smaller still */
@media (min-width: 360px) and (max-width: 379px) {
  .cpn:not(.cpn--compact) .was { font-size: 14px; } .cpn:not(.cpn--compact) .was s { font-size: 1.3em; }
  .cpn:not(.cpn--compact) .was[data-n="9"] s { font-size: 1.15em; }
  .cpn:not(.cpn--compact) .was[data-n="10"] s, .cpn:not(.cpn--compact) .was[data-n="11"] s { font-size: 1em; }
}
@media (min-width: 900px) and (max-width: 1219px) {
  .cpn:not(.cpn--compact) .value[data-n="8"] { font-size: clamp(60px, 60px + (100vw - 900px) * .035, 67px); }
  .cpn:not(.cpn--compact) .value[data-n="9"] { font-size: clamp(54px, 54px + (100vw - 900px) * .035, 61px); }
  .cpn:not(.cpn--compact) .value[data-n="10"], .cpn:not(.cpn--compact) .value[data-n="11"], .cpn:not(.cpn--compact) .value[data-n="12"] { font-size: clamp(48px, 48px + (100vw - 900px) * .04, 56px); }
}

/* FIX ROUND 9 (RL28 a; C2 round 9 m1 and m2): the first phone screen with the browser's bars. At 390 by 664 the sticky bar is hidden while
   the ticket is on screen, so the ticket's own button must show: at least its upper half on every page whose brand name takes one line, and
   the field and the consent box on every page (SkyScout's three line heading included). The phone face is 36 px tighter above the button,
   with every type size the identity's and every tap target where it was: the header band 4 px (the logo's 46 px link keeps its box), the
   hero 9.5 px (its top and bottom paddings 6, the deck's margin 2, the h1's leading at 1.0, the identity's own lower bound for display
   type, 1.5), the ticket's face 8 px (its top padding, the receipt line's margin, the value row's and the struck line's margins), the
   tear 8 px (the face's foot and the stub's head, 8 px each side of the dashed line), the field 6.5 px (its label's margin and leading;
   the field 52 px tall, its 17 px text and its 2 px rule as they were). The consent row keeps its 12 px above and below: the box's 44 px target reaches
   10 px above the row and the privacy link's 44 px box 11.5 px below its line (fix round 11), so neither reaches the field or the button.
   From 540 px nothing changes. */
@media (max-width: 539px) {
  .top { min-height: 48px; padding: 1px 0; }
  .hero { padding: 0 0 4px; }
  .hero h1 { line-height: 1; }
  .hero__deck { margin-top: 4px; }
  .cpn:not(.cpn--compact) .cpn__face { padding-top: 6px; padding-bottom: 8px; }
  .cpn:not(.cpn--compact) .cpn__hdr { margin-bottom: 6px; }
  .cpn:not(.cpn--compact) .cpn__value { margin-top: 7px; }
  .cpn:not(.cpn--compact) .was { margin-top: 3px; }
  .cpn:not(.cpn--compact) .cpn__stub { padding-top: 8px; }
  .claim .field-label { margin-bottom: 4px; line-height: 1.2; }
  .claim .field { height: 52px; }
}
/* FIX ROUND 9: the compact coupon's check line breaks before its stamp words, never inside them ("checked Oct 24", and the live check's
   "checked 12 sec ago"): the date or the count and its unit stay together on the narrow columns of the long prints */
.check [data-check] { white-space: nowrap; }

/* FIX ROUND 9 INTEGRATION (RL29 a; C1 round 9 m7): the hero stamp never runs into the window's picture cell. On the phone face the stamp lies
   in the window's first column, and its two lines ("Official store kr12990.00" over the check) ran up to 34 px into the white cell at 360 px
   (5.7 px in euros at 360, 33.8 in kronur), and into the device on the identity window, from 360 to 429 px. There the stamp now sets the
   store's figure on a line of its own, under "Official store" and over the check (a rubber stamp's title, value and date): the first line is
   a grid of two rows, so the stamp is as wide as its longest line, the figure or the check, never the two together; the type keeps its
   15 px and weight, the lines their 15 px with no gap, the tracking 0 and the padding 5, 6 and 6 px, the margins 7.5 and 10 px, so the
   stamp's block is the two line stamp's 77.5 px and nothing under the window moves (the first screen of RL28 measured the same before and
   after in the thirteen trees). The live check's longest words ("checked 59 min ago", "checked 12 days ago") keep clear at 360 px. From 360
   to 399 px a store window also grows with what it holds, so a two line name over a long sub line keeps its stamp inside the vermilion
   (SkyScout at 360 by 740 hung 27 px over the window's foot; the rows were that tall already, so the ticket under the window does not move);
   the identity window keeps its 168 px, its picture would set a taller height of its own. Under 360 px the stamp stands under the window and
   its tilted end touched the window's foot: it sits 4 px lower. */
@media (min-width: 360px) and (max-width: 429px) {
  .cpn__row .stamp { line-height: 1; gap: 0; padding: 5px 6px 6px; margin-block: 7.5px 10px; letter-spacing: 0; }
  .cpn__row .stamp__line:first-child { display: grid; justify-items: start; gap: 0; }
}
@media (min-width: 360px) and (max-width: 399px) { .cpn:not(.cpn--compact) .window--store { height: auto; min-height: 168px; align-self: stretch; } }
@media (max-width: 359px) { .cpn__row .stamp { margin-block-start: 18px; } }

/* FIX ROUND 10 (C1A m5, C1B m8): two scene pictures of one shape share the proof's row equally from 700 px (gen.py's shots--even), so the
   two cards end together; the 3fr 2fr row stays for a 3:2 picture beside a square (XtraBoost, PureWatt), whose cards it already evens.
   (RL36 b, C1A m3) a questions block of one question is one column from 700 px: no grid column stands empty beside it. */
@media (min-width: 700px) { .shots--even { grid-template-columns: 1fr 1fr; } .qa--one { grid-template-columns: minmax(0, 1fr); } }

/* STAGE 3 (BRIEF-STAGE3 section 3, FONTS PER SCRIPT): on a Bulgarian or Greek page the text role is Sofia Sans for every letter, its Latin
   too (the digits, the prices and the brand names in a deck or an answer), so one design paints a line; the display role stays the
   identity's condensed face in every script */
:lang(bg), :lang(el) { --text: "Sofia Sans", "cpon Currency Text", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif; }

/* STAGE 3 (EXTEND-PLAN W21): long words in the other languages (a German, Finnish or Hungarian compound) never push a tile, a pill, a fact
   card or a heading past its box: they break where they must, and the prose hyphenates in the page's language. English pages keep the
   measured layout as it is (these rules name every language but English). The consent label's last sentence yields its one line under
   360 px, where a long one would overflow the 222 px column. */
html:not([lang="en"]) .tile__cat, html:not([lang="en"]) .tile__name, html:not([lang="en"]) .pill, html:not([lang="en"]) .fact__big, html:not([lang="en"]) .kicker, html:not([lang="en"]) .rcpt, html:not([lang="en"]) .btn__label { overflow-wrap: anywhere; }
html:not([lang="en"]) h1, html:not([lang="en"]) h2, html:not([lang="en"]) h3, html:not([lang="en"]) .cpn__sub { overflow-wrap: break-word; }   /* the run 18 fix round's second build: the sub line under the brand's name too, which also hyphenates as the prose does (German SonicStop's Schädlingsvertreiber at 320 px) */
html:not([lang="en"]) .hero__deck, html:not([lang="en"]) .home-hero__deck, html:not([lang="en"]) .sec__lead, html:not([lang="en"]) .qa p, html:not([lang="en"]) .fact p, html:not([lang="en"]) .step p, html:not([lang="en"]) .about, html:not([lang="en"]) figcaption, html:not([lang="en"]) .fine p, html:not([lang="en"]) .prose p, html:not([lang="en"]) .page-head p, html:not([lang="en"]) .quote p, html:not([lang="en"]) .cpn__sub { -webkit-hyphens: auto; hyphens: auto; }
@media (max-width: 359px) { html:not([lang="en"]) .consent__text .nobr { white-space: normal; } }

/* STAGE 3 (RL31 g): the footer's list of the live languages, each by its own name, linking the same page in that language (no flags); it
   shows from the first wave that makes a second language live, under the footer's links, in the footer's small type with 44 px targets */
.foot__langs { display: flex; flex-wrap: wrap; gap: 0 6px; list-style: none; margin: 10px 0 0; padding: 0; }
.foot__langs a { display: inline-block; min-height: 44px; padding: 12px 8px; font-size: 14px; line-height: 20px; color: var(--grey-3); text-decoration: none; }
.foot__langs li:first-child a { padding-inline-start: 0; }
.foot__langs a:hover { color: var(--paper); text-decoration: underline; text-underline-offset: 4px; }
.foot__langs a[aria-current="page"] { color: var(--paper); font-weight: 600; }

/* STAGE 2C (RL44 (2), run 16): THE BOX BLOCK. Where no real review exists, the review's place shows the store's own picture of what comes
   in the box with its caption, and no quote, no source line, no review claim. The picture takes the review picture's width and its own
   shape, as every review picture does (the store's square on its own ground: a frame of XtraBoost's 1080 by 800 would band the three
   pictures whose ground is not white, FurVac 360's grey among them). On the phone it is the card of a scene (the picture, the caption under
   it). From 700 px it is one card across the row: the picture in the review picture's own column ((the row less the review's 36 px gap)
   times two fifths, the 2fr of .review), the caption beside it where the quote stands, a step larger in the ink so the row reads as one
   object, never as a quote (the text face, no accent rule, no source line). */
.review--box { display: block; }
@media (min-width: 700px) {
  .boxshot { display: grid; grid-template-columns: calc((100% - 36px) * .4) minmax(0, 1fr); align-items: center; }
  .boxshot figcaption { padding-block: 24px; padding-inline: 36px; font-size: 20px; line-height: 1.45; color: var(--ink); max-width: 36ch; }
}

/* RUN 16'S FIX ROUND (C1 m4 of s2c-r1; RL52 rules the layout of a block that keeps only part of itself the author's): a quote without a
   picture (AcheSoothe's) stands centred in its row from 700 px with its own measure and accent rule, a pull quote under the wide scene,
   never a block whose picture is missing (on the phone it is the quote as it was) */
@media (min-width: 700px) { .review--quote { justify-items: center; } }

/* STAGE 3, RL50 (a) (run 16's fix round; the ear critics of run 10: da B1, fi B1, fr B1, it B1, nl B1 and M1 and M2, de M5): NO HYPHEN THE
   READER DID NOT TYPE. On a page in another language the generator puts every brand name, review site, company, the requisites, every
   email address and every web address of the text in a span.nohy (gen.py nohy_text), the confirmation page's address stands in its
   strong.addr; these, every link and the name classes never take an automatic hyphen. An address or a link may still break anywhere, with
   no mark drawn (nohy--wrap); the requisites' own hyphens (LT-14188, 364-49) never end a line (nohy--keep). The prose keeps the language's
   hyphenation on the phone for long words only (ten letters at least, four kept on each side: no Mar-ke, ei-nen, Litau-en or Zo-als; the
   limits count what the engine counts with a word, its punctuation, an opening quote and a glued short word, so they stand higher than the
   letters they keep) and none from 700 px, where every column holds the language's longest word whole (it m10). */
html:not([lang="en"]) .nohy, html:not([lang="en"]) .addr, html:not([lang="en"]) a, html:not([lang="en"]) .cpn__name, html:not([lang="en"]) .tile__name, html:not([lang="en"]) .row__name { -webkit-hyphens: manual; hyphens: manual; }
.nohy--wrap { overflow-wrap: anywhere; }
.nohy--keep { white-space: nowrap; }
.hy-join { white-space: nowrap; }   /* the run 18 fix round (C2 M2): an address's own hyphen never ends a line, where a reader takes it for a hyphenation (gen.py hy_join, unlock.php) */
html:not([lang="en"]) .hero__deck, html:not([lang="en"]) .home-hero__deck, html:not([lang="en"]) .sec__lead, html:not([lang="en"]) .qa p, html:not([lang="en"]) .fact p, html:not([lang="en"]) .step p, html:not([lang="en"]) .about, html:not([lang="en"]) figcaption, html:not([lang="en"]) .fine p, html:not([lang="en"]) .prose p, html:not([lang="en"]) .page-head p, html:not([lang="en"]) .quote p, html:not([lang="en"]) .cpn__sub { hyphenate-limit-chars: 13 7 7; -webkit-hyphenate-limit-before: 7; -webkit-hyphenate-limit-after: 7; }   /* the run 18 fix round (C2 m1): the engine counts a word's punctuation, an opening quote and a glued short word with it, so the limits allow for them: no split under ten letters or four on a side */
html:lang(it) :is(.hero__deck, .home-hero__deck, .sec__lead, .qa p, .fact p, .step p, .about, figcaption, .fine p, .prose p, .page-head p, .quote p, .cpn__sub) { hyphenate-limit-chars: 13 9 7; -webkit-hyphenate-limit-before: 9; }   /* Italian counts an elided article with its word (dall'af-fidamento): nine before the break, so four letters of the word stand there */
@media (min-width: 700px) { html:not([lang="en"]) .hero__deck, html:not([lang="en"]) .home-hero__deck, html:not([lang="en"]) .sec__lead, html:not([lang="en"]) .qa p, html:not([lang="en"]) .fact p, html:not([lang="en"]) .step p, html:not([lang="en"]) .about, html:not([lang="en"]) figcaption, html:not([lang="en"]) .fine p, html:not([lang="en"]) .prose p, html:not([lang="en"]) .page-head p, html:not([lang="en"]) .quote p, html:not([lang="en"]) .cpn__sub { -webkit-hyphens: manual; hyphens: manual; } }

/* STAGE 3, RL50 (b) (run 16's fix round; the he critic of run 10, M3 to M5 and m9): on a right to left page a brand name reads left to right
   but aligns to its card's start, the right, as the lines beside it do (the hero window, the compact coupon, the tile); the compact
   coupon keeps its own row columns (the identity window's right to left columns above now reach the hero and the closing coupon only);
   the receipt type keeps the lower case cpon (no uppercase reaches a Latin name on a Hebrew page) and no tracking spaces the Hebrew
   letters, nor on the pill, the button or the check line */
[dir="rtl"] .cpn__name, [dir="rtl"] .tile__name { text-align: end; }
@media (max-width: 539px) { [dir="rtl"] :where(.cpn:not(.cpn--compact)) .cpn__row:not(.cpn__row--identity) > .cpn__name { margin-left: 0; margin-right: 14px; } }   /* the run 18 fix round's second build (C2 m3): on the store window's row the name's 14 px stand at its own start, the window's right edge, as the sub line's do */
[dir="rtl"] .rcpt { text-transform: none; letter-spacing: 0; }
[dir="rtl"] .pill, [dir="rtl"] .btn, [dir="rtl"] .check { letter-spacing: 0; }

/* THE HOME HERO ART (the home hero programme, 2026-10-28; build/home-hero/final-h7/FINAL.md and build/home-hero/proto/PROTO.md): on the
   homepage only, the brand's picture (five blank tickets in the mark's cut in flight, a ChatGPT Images 2.5 picture on the band's own
   vermilion, its outer 11 percent baked to #FC501F) stands in the band's right column from 700 px in place of the product picture;
   .home-hero__pic and its rules stay for the unlock confirmation page. (a) Under 700 px nothing changes: no art, its source there the 1
   pixel GIF. (b) The art is anchored to the content wrap: its inline end is the wrap's end plus (d) the overshoot, the wrap's margin
   beyond the 16 px page gutter, at most 40 px, so it never reaches the viewport's edge. (c) Its box never enters the text column, and the
   frame's plain outer 11 percent keeps the object clear of the search box. (e) Its size: a square as large as the right column allows
   and as the band allows centred on the text block (the kicker's top to the featured line's bottom), its top no higher than the
   header's bottom (314 px at 700, 426 at 1349 in English); from 1350 px (round 7, build/home-hero/round7/layout/LAYOUT.md) it hangs
   from the header: its box runs from the header's bottom to 68 px under the featured line, and the square is as large as that box, the
   column and 470 px allow (469.7 px in English), centred in it. (f) The band's height and the text column's widths are the rules
   above. (g) Right to left mirrors by the logical inset; the picture is never mirrored. (h) The frame's outer 11 percent is feathered
   to transparent, across on the box and down on the picture (the second guard: the picture's own edge is the band). If the hero's type
   or spacing changes, update --art-hv and top in the base rules (the 1350 px rule's --art-hv too) and the padding pairs in the anchor
   layer. */
.band--home .home-art { display: none; }
@media (min-width: 700px) {
  .band--home .home-art {
    /* the text block in English to 899 px: the kicker 19.5 + 10, the h1 two lines at line height 1.02 (4vw + 22px), the deck two lines
       of 17 px at 1.4 with its margins 10 and 18 (75.6), the search box 64, the featured line 10 + 24; and the hero's top padding twice */
    --art-hv: calc(2 * 16px + 29.5px + 2.04 * (4vw + 22px) + 75.6px + 64px + 34px);
    /* the right column: the wrap less the text column (53 percent of the wrap to 899 px) */
    --art-col: calc((100% - 32px) * .47);
    --art-over: clamp(0px, (100% - 1232px) / 2, 40px);
    --art-size: min(var(--art-col) + var(--art-over), var(--art-hv));
    --art-feather: transparent 0, rgb(0 0 0 / .104) 2.2%, rgb(0 0 0 / .352) 4.4%, rgb(0 0 0 / .648) 6.6%, rgb(0 0 0 / .896) 8.8%, #000 11%,
      #000 89%, rgb(0 0 0 / .896) 91.2%, rgb(0 0 0 / .648) 93.4%, rgb(0 0 0 / .352) 95.6%, rgb(0 0 0 / .104) 97.8%, transparent 100%;
    display: block;
    position: absolute;
    top: 52px;                                                       /* the header's bottom to 899 px */
    inset-inline-end: calc(max(16px, (100% - 1200px) / 2) - var(--art-over));
    width: var(--art-size);
    aspect-ratio: 1;
    margin: calc((var(--art-hv) - var(--art-size)) / 2) 0 0;         /* centred on the text block (a percentage margin is of the width) */
    -webkit-mask-image: linear-gradient(to right, var(--art-feather));
    mask-image: linear-gradient(to right, var(--art-feather));
  }
  .band--home .home-art picture { display: block; }
  .band--home .home-art img {
    width: 100%;
    height: auto;
    -webkit-mask-image: linear-gradient(to bottom, var(--art-feather));
    mask-image: linear-gradient(to bottom, var(--art-feather));
  }
}
@media (min-width: 900px) {
  .band--home .home-art {
    /* from 900 px: the hero's top padding 24, the h1 at min(4vw + 22px, 76px), the deck of 19 px at 1.4 with its margins 16 and 26 (95.2) */
    --art-hv: calc(2 * 24px + 29.5px + 2.04 * min(4vw + 22px, 76px) + 95.2px + 64px + 34px);
    /* 900 to 1199 px the text column is 55 percent of the wrap plus (100vw - 900px) * .19 (site.css, polish round 5) */
    --art-col: calc((100% - 32px) * .45 - (100vw - 900px) * .19);
    top: 64px;                                                       /* the header's bottom from 900 px */
  }
}
@media (min-width: 1200px) {
  .band--home .home-art { --art-col: calc(min(100% - 32px, 1200px) - 720px); }   /* the text column is 720 px */
}
@media (min-width: 1350px) {
  .band--home .home-art {
    /* from 1350 px (round 7): the box runs from the header's bottom to 68 px under the featured line, English's present box plus 44
       (469.7 px); the square fills it, so it hangs from the header, and it is never larger than 470 px */
    --art-hv: calc(2 * 24px + 29.5px + 2.04 * min(4vw + 22px, 76px) + 95.2px + 64px + 34px + 44px);
    --art-size: min(var(--art-col) + var(--art-over), var(--art-hv), 470px);
    margin: 0;                                                       /* hung from the header: its top is top, 64 px */
  }
}
/* (e) in every language and engine with CSS anchor positioning (Chromium 125, Safari 26): the art is sized and centred on the text block
   the page set (the text column is the anchor; its height less its padding-bottom is the text block), so a headline or a deck of three
   lines in another language keeps the art on the block's centre (from 1350 px on the centre of its box, which runs from the header's
   bottom to 68 px under the featured line: 22 px lower); a browser without it keeps English's geometry above */
@supports (top: anchor(--a bottom)) and (width: anchor-size(--a height)) {
  .band--home .home-hero__text { anchor-name: --cpon-hero-text; }
  @media (min-width: 700px) {
    .band--home .home-art {
      --art-hv: calc(anchor-size(--cpon-hero-text height) - 36px + 2 * 16px);     /* the text block (less padding-bottom 36) + 2 x 16 */
      bottom: calc(anchor(--cpon-hero-text bottom) + 36px - 16px);
      margin: auto 0;
    }
  }
  @media (min-width: 900px) {
    .band--home .home-art {
      --art-hv: calc(anchor-size(--cpon-hero-text height) - 48px + 2 * 24px);     /* the text block (less padding-bottom 48) + 2 x 24 */
      bottom: calc(anchor(--cpon-hero-text bottom) + 48px - 24px);
    }
  }
  @media (min-width: 1350px) {
    .band--home .home-art {
      --art-hv: calc(anchor-size(--cpon-hero-text height) - 48px + 24px + 68px);   /* the text block + 24 + 68 */
      bottom: calc(anchor(--cpon-hero-text bottom) + 48px - 68px);                /* 68 px under the featured line */
      margin: auto 0;                                                              /* the square centred in its box */
    }
  }
}

/* RUN 18, RL54 (c): THE STAMP SAYS CHECKED IN EVERY LANGUAGE (the operator's "validated seconds ago" is the stamp's job, in every state of the
   live count). English keeps its measured stamp (RL29, RL36: its longest words stand clear at every width). On a page in another language
   the stamp's lines may wrap inside the stamp, and the stamp never leaves its column: the check words take a second line when they must,
   balanced, the count with its unit and the date whole (the generator's no-break spaces); the store's title keeps its line and its figure
   moves under it first. From 360 to 429 px, where the stamp lies in the phone window's first column, the name, the sub line and the
   stamp sit 7.5 px tighter, so a four line stamp under a one line name and a two line sub line fits the 168 px window; a window that must
   hold more grows (the picture keeps its own size, centred on its own ground), from 400 to 539 px past its picture's own height. Under 360
   px the stamp stands under the window across the face, 6 px lower than English's, so a stamp as wide as the face clears the window with
   its tilt. Proved at every width from 320 to 430 px in every language with the longest words and prints (bin/r18/stamp18.mjs). */
html:not([lang="en"]) .stamp { white-space: normal; }
html:not([lang="en"]) .stamp__line { min-width: 0; }
html:not([lang="en"]) .stamp__line:first-child { flex-wrap: wrap; row-gap: 0; }
html:not([lang="en"]) .stamp [data-check] { min-width: 0; text-wrap: balance; }
html:not([lang="en"]) .cpn__row .stamp { max-width: calc(100% - 10px - 6px); }
@media (max-width: 359px) { html:not([lang="en"]) .cpn__row .stamp { max-width: calc(100% - 2px - 6px); margin-block-start: 24px; } }
@media (min-width: 360px) and (max-width: 429px) {
  html:not([lang="en"]) .cpn__row .cpn__name { margin-block-start: 12px; }
  html:not([lang="en"]) .cpn__row .cpn__sub { margin-block-start: 3px; }
  html:not([lang="en"]) .cpn__row .stamp { padding-block: 4px 5px; margin-block-end: 7.5px; }
}
@media (min-width: 360px) and (max-width: 399px) {
  html:not([lang="en"]) .cpn:not(.cpn--compact) .window:not(.window--gen):not(.window--store) { position: relative; height: auto; min-height: 168px; align-self: stretch; }
  html:not([lang="en"]) .cpn:not(.cpn--compact) .window:not(.window--gen):not(.window--store) img { position: absolute; inset: auto 0; top: 50%; height: auto; aspect-ratio: 1240 / 697; transform: translateY(-50%); }
}
@media (min-width: 400px) and (max-width: 539px) {
  html:not([lang="en"]) .cpn:not(.cpn--compact) .window { position: relative; align-self: stretch; height: auto; aspect-ratio: auto; }
  html:not([lang="en"]) .cpn:not(.cpn--compact) .window::before { content: ""; display: block; padding-top: calc(100% * 697 / 1240); }
  html:not([lang="en"]) .cpn:not(.cpn--compact) .window:not(.window--store) img { position: absolute; inset: auto 0; top: 50%; height: auto; aspect-ratio: 1240 / 697; transform: translateY(-50%); }
}
/* the compact coupon's check line: the stamp's words may wrap in its narrow column (the count with its unit, the date whole), never cut */
html:not([lang="en"]) .check [data-check] { white-space: normal; }

/* RUN 18, RL54 (d), RL28 (a) WITH A THREE LINE CONSENT LABEL: at 390 by 664 the claim button shows at least its upper half in every language,
   a lawful label of three lines included (Bulgarian today: its middle at 683.8 px before, 661.8 now, English's own). On a phone page in
   another language the first ticket is 22 px tighter above the button, every type at its size (the label's 15 px) and every tap target
   where it was: the field 46 px tall (its 17 px text and 2 px rule), its label 2 px closer, the consent row 10 px under the field (the
   box's 44 px target reaches 10 px above the row: it meets the field, never crosses it), the label's leading 1.3 (its link's 44 px box
   12.25 px under its line, the row's foot 12.5 px), the tear 5 px each side, the value row 5 px under the window. A language's other
   lines (run 11's headings and decks) keep the room this gives. */
@media (max-width: 539px) {
  html:not([lang="en"]) .claim .field { height: 46px; }
  html:not([lang="en"]) .claim .field-label { margin-bottom: 2px; }
  html:not([lang="en"]) .claim .consent { margin-block: 10px 12.5px; }
  html:not([lang="en"]) .claim .consent__text { line-height: 1.3; }
  html:not([lang="en"]) .claim .consent__text a { padding-block: 12.25px; margin-block: -12.25px; }
  html:not([lang="en"]) .cpn:not(.cpn--compact) .cpn__face { padding-bottom: 5px; }
  html:not([lang="en"]) .cpn:not(.cpn--compact) .cpn__stub { padding-top: 5px; }
  html:not([lang="en"]) .cpn:not(.cpn--compact) .cpn__value { margin-top: 5px; }
}

/* RUN 18, RL54 (f): THE 320 PX CONTAINER, for every language at once. (1) The footer's links may take two rows: every link keeps its 12 px
   sides and the row starts 12 px before the column, so a wrapped link stands under the first one's text, never 12 px in (bg, cs, et, hu,
   nl at 320); the language list the same with its 8 px; the English row draws its text where it was. (2) The search field's empty clear
   button reserves no room, so the placeholder shows whole at 320 (bg, cs: "напр. XtraBoost"). (3) A word of one or two letters next to a
   tile pill's price joins it (the generator's span.pr-join), so a two line pill reads "COUPON" over "À €26.99", never a lone "À". (4) A
   word of the e-mail family keeps its hyphen (the generator's span.nohy--keep), so no line ends on a lone "e-". */
.foot__links { margin-inline-start: -12px; }
.foot__links li:first-child a { padding-inline-start: 12px; }
.foot__langs { margin-inline-start: -8px; }
.foot__langs li:first-child a { padding-inline-start: 8px; }
.search__input:placeholder-shown::-webkit-search-cancel-button { display: none; }
.pr-join { white-space: nowrap; }
/* THE RUN 18 FIX ROUND (C1 m4 of run 18): from 760 to 899 px the hero's and the homepage's stamp stand in the row's own auto column, which
   their words size, so a cap of that column less 16 px wrapped the store's figure onto a line of its own and still let long words widen the
   column into the price's: there the stamp has a measure of its own, wide enough for every language's store words and their euro print on
   one line, long words wrap inside it, and the price's column keeps the price's own width, so the stamp's column takes what it leaves */
@media (min-width: 760px) and (max-width: 899px) {
  html:not([lang="en"]) .cpn:not(.cpn--compact) .cpn__row { grid-template-columns: 200px minmax(min-content, 1fr) auto; }
  html:not([lang="en"]) .cpn:not(.cpn--compact) .cpn__row .stamp { max-width: 15em; }
}
html:not([lang="en"]) .tile .pill { line-height: 1.1; }   /* a half tile's two line pill reads as one badge (it, et, hu, nl, fr at 320 to 375) */
/* RUN 12 (wave fr) FIX (the wave critic's M1 of wave-fr-r1; LEAD-NOTE item 15): FROM 700 PX A PROOF CARD'S FIGURE WRAPS AS THE ENGLISH ONE,
   in every language. The three cards share a row sized by their content (budgets.json sheet.proof.cards.big), so a figure word wider than
   an even share widens its card, as an English one does, and is never cut inside with no mark (W21's overflow-wrap anywhere above kept the
   row's three columns even and cut French 'Bluetoot / h' at 768 to 798 px and '12 000 par m / inute' at 792 to 946 px). From 700 px a
   figure takes no automatic hyphen (the rule of RL50 a), so it divides only at a writer's soft hyphen, with its mark. Under 700 px the card
   is the column's own width and cannot grow: there the last resort break stays, behind the language's hyphenation, for a word wider than
   the card (normal would scroll the page sideways). */
@media (min-width: 700px) { html:not([lang="en"]) .fact__big { overflow-wrap: normal; } }
/* RUN 21 (LEAD-NOTE item 11; the German wave critic's m2): THE TILE WALL'S PILLS LEVEL. The wall's rows stretch their tiles to the row's
   height, and a tile's stub fills what its picture leaves; the pill stood under the category, so a tile whose category or name takes a line
   more set its pill a line lower than its neighbours' (German at every width, English where a category wraps). The pill now stands at the
   stub's foot (the stub's third row takes the room), so every pill of a row stands level at its foot, a pill of two lines beside pills of
   one included; the name and the category keep their place, no tile and no row changes its height (tiles-c21.mjs, 22 widths, every
   language). */
.tile__stub { grid-template-rows: auto auto 1fr; }
.tile__status { align-self: end; }
/* RUN 21 (LEAD-NOTE items 12 and 19; the German wave critic's m3, the Spanish ear critic's m1): THE STAMP'S ROOM UNDER THE SUB LINE. From 360
   to 429 px the stamp lies under the name and the sub line in the phone window's first column, turned 4 degrees about its start, so its far
   end rises by about a fourteenth of its width (10.5 px for a stamp of 150 px) and its outline 3 px beyond that. With 7.5 px above it, a
   wide stamp (four lines, or a long live form or print) under a long last line of the sub line drew its top edge up to 6.6 px into that
   line's box: into its empty descender band and onto the descenders of Mbps, kg or lens (every page of the 21 frames and the English tree,
   every live form and the longest print: stamproom-c21.mjs). The stamp keeps 15 px above it there in every language, and the window keeps
   its height in every language: where the name, the sub line and the stamp fill it (run 18 fitted a stamp of four lines under a one line
   name and a sub line of two to the 168 px exactly; an English name of two lines over a sub line of two sets SkyScout Monocular's window
   at 186.5 px), a taller window would move the first screen (RL28 a: the Bulgarian and Swedish buttons keep 2 to 3 px over their half,
   SkyScout's English consent box 6 px over the fold at 390 by 664: fold18.mjs) and would jump as the live count walks from form to form.
   So the 7.5 px come from inside the window, none of them from the sub line's lines, so the window keeps its height whatever their count:
   the name stands 3 px higher (11 px under the window's top for 14 in English, 9 for 12 in another language), the sub line 3 px nearer
   the name (1 px for 4 in English, 0 for 3 in another language: the name's descenders end inside its line box, so about 4 px stay
   between them and the sub line's ascenders) and the stamp keeps 1.5 px less under it (8.5 px for 10 in English, 6 for 7.5 in another
   language; its outline stays inside the window's foot). */
@media (min-width: 360px) and (max-width: 429px) {
  .cpn__row .stamp { margin-block-start: 15px; }
  .cpn:not(.cpn--compact) .cpn__row .cpn__name { margin-block-start: 11px; }
  html:not([lang="en"]) .cpn:not(.cpn--compact) .cpn__row .cpn__name { margin-block-start: 9px; }
  .cpn:not(.cpn--compact) .cpn__row .cpn__sub { margin-block-start: 1px; }
  html:not([lang="en"]) .cpn:not(.cpn--compact) .cpn__row .cpn__sub { margin-block-start: 0; }
  .cpn:not(.cpn--compact) .cpn__row .stamp { margin-block-end: 8.5px; }
  html:not([lang="en"]) .cpn:not(.cpn--compact) .cpn__row .stamp { margin-block-end: 6px; }
}
/* RUN 21 (LEAD-NOTE item 20; the Spanish ear critic's m2): THE STICKY BAR'S PAIR. On a phone the bar sets the price and its sub line beside the
   button, so the sub line's room is what the language's own button leaves: UNLOCK leaves the English sub 178 px at 320, LO QUIERO 162, FÅ
   PRISEN 165, and the sub took two lines where the English holds one in fifteen languages. On a page in another language the button keeps
   14 px a side and the bar's gap is 8 px, 16 px more for the sub; with them the sub keeps one line wherever the English one does, the
   Danish pair but for eight names (stickypair-c21.mjs, every published name at 24 widths). The pair's budget with each language's own
   button: stage2/ui/README.md and budgets.json coupon.shortcut_pair. */
/* RUN 12 (wave es; LEAD-NOTE item 23, C2-r21-r1 M1): THE PAIR WITH 1 PX OF MARGIN. The Spanish pair stood on its budget (the estimate
   245.5 px against 244.8 of room, both printed as 245), and at 324 px the browser drew 'HarmonyMat Pro · válido hoy' in 182.5 px of text
   against 181.95 px of room, so it wrapped after its raised dot where the English holds one line (and SkyScout Monocular at 347). The
   button now keeps 13 px a side on a page in another language (14 in run 21): the sub line has 18 px more than the English bar's, and the
   pair's budget keeps 1 px of that room as its margin (tools/sheet-diff.py, budgets.json coupon.shortcut_pair), so the estimate's error
   never reaches the line: the Spanish pair stands 1.3 px under the room (sticky1px-w12es.mjs, every published name in every language at
   every width from 320 to 767 px, DPR 2). */
html:not([lang="en"]) .sticky { gap: 8px; }
html:not([lang="en"]) .sticky__btn { padding-inline: 13px; }
/* RUN 21 (LEAD-NOTE item 21; the Spanish ear critic's m5): A UNIT SYMBOL KEEPS ITS OWN CASE INSIDE THE STAMP'S CAPITALS. The live check writes
   the count's symbol in a span.num__u (pricecheck.js units(): s and h, and min where the language writes its second or its hour by its
   symbol), so the capitals print COMPROBADO HACE 47 s and 59 min, never 47 S (the siemens); an abbreviation (SEC, SEK., MIN., STD.) takes the
   capitals as the words do. */
.num__u { text-transform: none; }
/* RUN 12 (wave es; LEAD-NOTE item 26, touch-polish1-es-r1 m10): A LINK JOINED TO ITS WORD PARTS WITH IT. A prose link is drawn inline-block
   for its tap reach, and an inline-block is a break opportunity of its own, so a writer's no-break space before it held nothing: at 320 px
   the Spanish contact line read 'Puedes escribirnos a / hello@cpon.com cuando quieras.', the preposition left at the line's end. The
   generator marks a link that a no-break joint ties to its word (scripts/stage2/legaltext.py: class joined, where a no-break space, a
   narrow no-break space or a word joiner stands right before or after the link), and the stylesheet draws that link inline, so the joint
   holds and the word and the link part as one; its padding keeps the same reach (13.5 px a side of its 22 px content: a box 49 px tall,
   the inline-block's 49.2). Every other link keeps its box; English carries no joint, so nothing changes there. */
.prose a.joined { display: inline; padding-block: 13.5px; }
/* RUN 12 (wave it; LEAD-NOTE item 29, ear19-it-r1 m2): A LINK KEEPS THE MARK AFTER IT. The decline link is drawn inline-block for its tap
   reach, and an inline-block is a break opportunity of its own, so with the five figure Icelandic prints at 320 px the Italian line filled
   to the link's end and its full stop wrapped alone ('Oppure paga kr15099.99 sul sito ufficiale' / '.', 31 pages; the Finnish
   confirmation page alike at 320 and 332 px). On a page in another language the decline link, the coupon's and the confirmation page's,
   is drawn inline, so the mark after it stays with its last word; its padding keeps the reach (14.5 px a side of its 18 px content
   area: a box 47 px tall, the inline-block's 47). A legal page's link that a mark follows is marked joined by the generator
   (scripts/stage2/legaltext.py) and drawn inline by the rule above. English keeps its boxes (no English line ends so). */
html:not([lang="en"]) .decline a { display: inline; padding-block: 14.5px; }
