/*
  FrancisCreation storefront.

  Quiet page, loud product. Separation is done with hairline rules rather than shadows and cards,
  because the products are crisp machined objects and soft floating panels fight them.
*/

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

html {
  -webkit-text-size-adjust: 100%;
  /* A backstop, not a substitute for fixing the cause: one over-wide element should not make the
     whole site scroll sideways on a phone. */
  overflow-x: hidden;
}

body {
  margin: 0;
  font-family: var(--fc-font-sans);
  font-size: var(--fc-text-base);
  line-height: var(--fc-leading-normal);
  background: var(--fc-paper);
  color: var(--fc-ink);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: "kern" 1;

  /* Holds the footer against the bottom of the viewport on a short page - a sign-in form or an
     empty cart - without pinning it there on a long one. dvh rather than vh so a mobile browser's
     collapsing address bar does not leave a strip of blank page below it. */
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

h1, h2, h3, h4 {
  margin: 0 0 var(--fc-space-4);
  font-weight: 600;
  line-height: var(--fc-leading-tight);
  letter-spacing: var(--fc-tracking-tight);
  text-wrap: balance;
}

h1 { font-size: clamp(var(--fc-text-3xl), 5vw, var(--fc-text-4xl)); }
h2 { font-size: clamp(var(--fc-text-2xl), 3.5vw, var(--fc-text-3xl)); }
h3 { font-size: var(--fc-text-xl); letter-spacing: var(--fc-tracking-snug); }
h4 { font-size: var(--fc-text-lg); letter-spacing: var(--fc-tracking-snug); }

p { margin: 0 0 var(--fc-space-4); }
p:last-child { margin-bottom: 0; }

a { color: inherit; text-decoration-color: var(--fc-rule-strong); text-underline-offset: 3px; }
a:hover { text-decoration-color: currentColor; }

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

/* One focus treatment everywhere, in the accent, so keyboard use is obvious and consistent. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--fc-accent);
  outline-offset: 2px;
  border-radius: var(--fc-radius-xs);
}

/*
  Blazor's FocusOnNavigate moves focus to the page heading after each navigation, which is right for
  screen reader users but paints a stray box around the title for everyone else. The focus move is
  kept; only its outline is suppressed, and headings are not otherwise reachable by tab.
*/
:where(h1, h2, h3, h4):focus,
:where(h1, h2, h3, h4):focus-visible { outline: none; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Wide content scrolls inside its own box; the page never scrolls sideways. */
.table-scroll { overflow-x: auto; scrollbar-width: thin; }

.eyebrow {
  font-size: var(--fc-text-2xs);
  font-weight: 650;
  letter-spacing: var(--fc-tracking-wide);
  text-transform: uppercase;
  color: var(--fc-accent);
  margin: 0 0 var(--fc-space-3);
}

/* ---------- Administrator bar ---------- */

/*
  Sits above the header and only for administrators. Dark and full width on purpose: it should never
  be mistaken for part of the shop, and it doubles as a reminder that you are not seeing what a
  customer sees.
*/
.admin-bar {
  background: var(--fc-ink);
  color: #d4d4d8;
  font-size: var(--fc-text-xs);
}

.admin-bar__inner {
  max-width: var(--fc-content);
  margin: 0 auto;
  padding: var(--fc-space-2) var(--fc-space-5);
  display: flex;
  align-items: center;
  gap: var(--fc-space-4);
}

.admin-bar__link {
  color: #fff;
  font-weight: 650;
  text-decoration: none;
  letter-spacing: var(--fc-tracking-snug);
}
.admin-bar__link:hover { text-decoration: underline; text-underline-offset: 3px; }

/* The action for this page, set apart from the section link beside it so the two do not read as
   one run of navigation. Outlined rather than underlined: it is a button in spirit. */
.admin-bar__link--context {
  color: #d4d4d8;
  font-weight: 550;
  padding: 1px var(--fc-space-2);
  border: 1px solid #3f3f46;
  border-radius: var(--fc-radius-xs);
}
.admin-bar__link--context:hover {
  color: #fff; border-color: #71717a; text-decoration: none;
}

/* Pushed to the right, and the first thing dropped when the strip runs out of room. */
.admin-bar__who { margin-left: auto; color: #8e8e97; }

/* Narrow screens keep the admin links and drop the address; it is the least useful thing here
   and the longest. */
@media (max-width: 34rem) {
  .admin-bar__who { display: none; }
}

/* ---------- Header ---------- */

.fc-nav {
  border-bottom: 1px solid var(--fc-rule);
  background: color-mix(in srgb, var(--fc-paper) 92%, transparent);
  backdrop-filter: saturate(160%) blur(14px);
  position: sticky;
  top: 0;
  z-index: 20;
}

.fc-nav__inner {
  display: flex;
  align-items: center;
  gap: var(--fc-space-4);
  width: 100%;
  max-width: var(--fc-content);
  margin: 0 auto;
  padding: var(--fc-space-3) var(--fc-space-5);
  min-height: 60px;
}

.fc-nav__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--fc-space-3);
  font-weight: 650;
  font-size: var(--fc-text-base);
  letter-spacing: var(--fc-tracking-snug);
  text-decoration: none;
  white-space: nowrap;
  min-width: 0;
}

/* Optically matched to the cap height of the name beside it, so the two read as one lockup. */
.fc-nav__mark { width: 26px; height: auto; flex-shrink: 0; }

/* Hidden by default and revealed at the breakpoint: on a phone these are what overflowed the row
   and made the whole page scroll sideways. */
.fc-nav__links { display: none; }

.fc-nav__actions { display: flex; align-items: center; gap: var(--fc-space-2); margin-left: auto; }

.fc-nav__link {
  font-size: var(--fc-text-sm);
  color: var(--fc-ink-muted);
  text-decoration: none;
  padding: var(--fc-space-2) 0;
  white-space: nowrap;
  /* A border rather than an underline, so the rule sits clear of the descenders. */
  border-bottom: 1.5px solid transparent;
  transition: color 140ms var(--fc-ease), border-color 140ms var(--fc-ease);
}
.fc-nav__link:hover { color: var(--fc-ink); border-bottom-color: var(--fc-accent); }

/* Sign out is a button because it posts, but it belongs with the links visually. */
.fc-nav__link--button {
  background: none; border: 0; border-bottom: 1.5px solid transparent;
  font: inherit; font-size: var(--fc-text-sm); cursor: pointer;
}
.fc-nav__signout { margin: 0; display: flex; align-items: center; }

.fc-nav__cart {
  display: inline-flex; align-items: center; gap: var(--fc-space-2);
  font-size: var(--fc-text-sm); font-weight: 550;
  padding: var(--fc-space-2) var(--fc-space-3);
  border: 1px solid var(--fc-rule-strong); border-radius: var(--fc-radius-sm);
  text-decoration: none; white-space: nowrap;
  transition: border-color 140ms var(--fc-ease);
}
.fc-nav__cart:hover { border-color: var(--fc-ink); }

.fc-nav__count {
  display: inline-grid; place-items: center;
  min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: 999px; background: var(--fc-accent); color: #fff;
  font-size: var(--fc-text-2xs); font-weight: 650; font-variant-numeric: tabular-nums;
}

/* ---- The narrow-screen menu ----
   A native <details>: no script, keyboard operable, and its open state is announced. */

.fc-nav__menu { position: relative; }

.fc-nav__toggle {
  display: grid; place-items: center;
  /* 44px, the smallest comfortable touch target. */
  width: 44px; height: 44px;
  border: 1px solid var(--fc-rule-strong); border-radius: var(--fc-radius-sm);
  cursor: pointer; list-style: none;
}
.fc-nav__toggle::-webkit-details-marker { display: none; }
.fc-nav__toggle::marker { content: ""; }

/* Three rules from one element, so the button needs no icon font and no image request. */
.fc-nav__bars, .fc-nav__bars::before, .fc-nav__bars::after {
  display: block; width: 17px; height: 1.5px;
  background: var(--fc-ink); border-radius: 2px;
  transition: transform 160ms var(--fc-ease);
}
.fc-nav__bars { position: relative; }
.fc-nav__bars::before, .fc-nav__bars::after { content: ""; position: absolute; left: 0; }
.fc-nav__bars::before { top: -5.5px; }
.fc-nav__bars::after { top: 5.5px; }

/* Becomes a cross while open, so the same control obviously closes it. */
.fc-nav__menu[open] .fc-nav__bars { background: transparent; }
.fc-nav__menu[open] .fc-nav__bars::before { transform: translateY(5.5px) rotate(45deg); }
.fc-nav__menu[open] .fc-nav__bars::after { transform: translateY(-5.5px) rotate(-45deg); }

.fc-nav__panel {
  position: absolute; right: 0; top: calc(100% + var(--fc-space-3));
  min-width: 13rem;
  display: flex; flex-direction: column;
  padding: var(--fc-space-2);
  background: var(--fc-paper);
  border: 1px solid var(--fc-rule);
  border-radius: var(--fc-radius-md);
  box-shadow: var(--fc-shadow-lg);
}

.fc-nav__panel-link {
  padding: var(--fc-space-3);
  border-radius: var(--fc-radius-sm);
  color: var(--fc-ink); text-decoration: none;
  font-size: var(--fc-text-sm);
}
.fc-nav__panel-link:hover { background: var(--fc-paper-raised); }

.fc-nav__panel-link.fc-nav__link--button {
  width: 100%; text-align: left; border: 0; color: var(--fc-ink);
}
.fc-nav__panel form { margin: 0; }
.fc-nav__panel-rule { border: 0; border-top: 1px solid var(--fc-rule); margin: var(--fc-space-2) 0; }

/* Above the breakpoint the links sit inline and the disclosure disappears. */
@media (min-width: 52rem) {
  .fc-nav__inner { gap: var(--fc-space-8); padding-inline: var(--fc-space-6); }
  .fc-nav__links { display: flex; gap: var(--fc-space-6); align-items: center; margin-left: auto; }
  .fc-nav__actions { margin-left: 0; }
  .fc-nav__menu { display: none; }
}

/* On the narrowest phones the brand name and the word "Cart" give way to their marks. */
@media (max-width: 26rem) {
  .fc-nav__brand span { display: none; }
  .fc-nav__cart-label { display: none; }
}

.fc-main {
  /* Takes the slack, which is what pushes the footer down. */
  flex: 1 0 auto;
  width: 100%;
  max-width: var(--fc-content);
  margin: 0 auto;
  padding: var(--fc-space-12) var(--fc-space-6) var(--fc-space-24);
}
.fc-main--flush { padding-top: 0; }

.fc-footer {
  flex-shrink: 0;
  border-top: 1px solid var(--fc-rule);
  padding: var(--fc-space-10) var(--fc-space-5);
  color: var(--fc-ink-muted);
  font-size: var(--fc-text-sm);
}

/* Stacked and centred on a narrow screen; two columns once there is room for them. Left-aligning
   a mark and two short lines against a phone's left edge just looks like leftovers. */
.fc-footer__inner {
  max-width: var(--fc-content);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--fc-space-5);
  text-align: center;
}

.fc-footer__brand img { width: 46px; height: auto; }
.fc-footer__text p { margin: 0 0 var(--fc-space-1); }
.fc-footer__text p:last-child { margin-bottom: 0; }

@media (min-width: 46rem) {
  .fc-footer { padding-inline: var(--fc-space-6); }
  .fc-footer__inner {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    text-align: left;
    gap: var(--fc-space-8);
  }
  .fc-footer__text { text-align: right; }
  .fc-footer__brand img { width: 52px; }
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--fc-space-2);
  padding: var(--fc-space-3) var(--fc-space-6);
  border: 1px solid transparent; border-radius: var(--fc-radius-sm);
  font: inherit; font-size: var(--fc-text-sm); font-weight: 600;
  letter-spacing: var(--fc-tracking-snug);
  cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: background-color 140ms var(--fc-ease), border-color 140ms var(--fc-ease),
              color 140ms var(--fc-ease), transform 80ms var(--fc-ease);
}
.btn:active { transform: translateY(1px); }

/* Ink, not accent. The buy action should read as settled and certain; the orange is reserved for
   things that need to catch the eye rather than close the sale. */
.btn--primary { background: var(--fc-ink); color: var(--fc-paper); }
.btn--primary:hover { background: #000; }

.btn--ghost { background: transparent; border-color: var(--fc-rule-strong); color: var(--fc-ink); }
.btn--ghost:hover { border-color: var(--fc-ink); }

.btn--block { width: 100%; }
.btn--small { padding: var(--fc-space-2) var(--fc-space-4); font-size: var(--fc-text-xs); }
.btn--buy { width: 100%; padding: var(--fc-space-4) var(--fc-space-6); font-size: var(--fc-text-base); }
.btn[disabled] { opacity: 0.35; cursor: not-allowed; }
.btn[disabled]:active { transform: none; }

/* ---------- Forms ---------- */

.field { margin-bottom: var(--fc-space-5); }
.field label {
  display: block; margin-bottom: var(--fc-space-2);
  font-size: var(--fc-text-xs); font-weight: 650;
  letter-spacing: var(--fc-tracking-wide); text-transform: uppercase;
  color: var(--fc-ink-muted);
}
.field--inline { display: flex; gap: var(--fc-space-3); align-items: flex-end; }
.field small { display: block; margin-top: var(--fc-space-2); font-size: var(--fc-text-xs); color: var(--fc-ink-muted); }

.input, .select {
  width: 100%;
  padding: var(--fc-space-3) var(--fc-space-4);
  border: 1px solid var(--fc-rule-strong);
  border-radius: var(--fc-radius-sm);
  background: var(--fc-paper);
  color: var(--fc-ink);
  font: inherit; font-size: var(--fc-text-sm);
  transition: border-color 140ms var(--fc-ease);
}
.input:hover, .select:hover { border-color: var(--fc-ink-faint); }
.input--qty { width: 5rem; text-align: center; font-variant-numeric: tabular-nums; }

/* ---------- Notices and badges ---------- */

/*
  A message set on the page, not a coloured bar stuck to the side of it.

  The old treatment was a thick tinted border down the left edge with the whole message set in that
  colour - the generic framework look. This carries the state in one small dot and leaves the words
  in ordinary ink, so it reads as part of the page rather than an alert bolted onto it: a hairline
  card, a soft shadow, room to breathe, and the colour used once where it means something.
*/
.notice {
  display: flex;
  align-items: baseline;
  gap: var(--fc-space-3);
  padding: var(--fc-space-4) var(--fc-space-5);
  border: 1px solid var(--fc-rule);
  border-radius: var(--fc-radius-md);
  background: var(--fc-paper);
  box-shadow: var(--fc-shadow-sm);
  color: var(--fc-ink-soft);
  font-size: var(--fc-text-sm);
  line-height: 1.6;
  margin: var(--fc-space-5) 0;
}
.notice::before {
  content: "";
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  margin-top: 0.35em;
  border-radius: 999px;
  background: var(--fc-ink-faint);
}
.notice--ok::before { background: var(--fc-instock); }
.notice--error::before { background: var(--fc-sale); }
.notice--preorder::before { background: var(--fc-preorder); }

/* An error is the one that earns a little more presence: a whisper of the accent behind it and a
   border to match, still a long way from a slab of colour. */
.notice--error {
  background: var(--fc-accent-tint);
  border-color: color-mix(in srgb, var(--fc-sale) 22%, var(--fc-rule));
}
.notice--out, .notice--info { color: var(--fc-ink-muted); }

.badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px var(--fc-space-2);
  border-radius: var(--fc-radius-xs);
  font-size: var(--fc-text-2xs); font-weight: 650;
  letter-spacing: 0.03em; text-transform: uppercase;
}
.badge--preorder { background: #fdf6e7; color: var(--fc-preorder); }
.badge--out { background: var(--fc-paper-sunken); color: var(--fc-out); }
.badge--verified { background: #eef7f1; color: var(--fc-instock); }
/* Retired, not out of stock: inked rather than tinted, so it does not read as a state
   that will pass. */
.badge--retired { background: var(--fc-ink); color: var(--fc-paper); }

/* A dot rather than a word where the state is obvious from context. */
.dot { width: 6px; height: 6px; border-radius: 999px; display: inline-block; }
.dot--in { background: var(--fc-instock); }
.dot--pre { background: var(--fc-preorder); }
.dot--out { background: var(--fc-ink-faint); }

/* ---------- Home ---------- */

.home-hero {
  padding: var(--fc-space-20) 0 var(--fc-space-16);
  border-bottom: 1px solid var(--fc-rule);
  margin-bottom: var(--fc-space-16);
}
.home-hero h1 {
  max-width: 20ch;
  font-size: clamp(var(--fc-text-3xl), 6vw, var(--fc-text-5xl));
  margin-bottom: var(--fc-space-6);
}
.home-hero__sub {
  max-width: var(--fc-prose);
  font-size: var(--fc-text-lg);
  color: var(--fc-ink-soft);
}

.section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--fc-space-4); margin-bottom: var(--fc-space-8);
}
.section-head h2 { margin: 0; font-size: var(--fc-text-xl); }
.section-head__meta { font-size: var(--fc-text-sm); color: var(--fc-ink-muted); }

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

.product-grid {
  display: grid;
  gap: var(--fc-space-10) var(--fc-space-6);
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}

.card { display: flex; flex-direction: column; text-decoration: none; color: inherit; }

.card__media {
  position: relative;
  aspect-ratio: 4 / 5;
  background: var(--fc-paper-raised);
  border: 1px solid var(--fc-rule);
  border-radius: var(--fc-radius-md);
  overflow: hidden;
  margin-bottom: var(--fc-space-4);
}
.card__media img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 400ms var(--fc-ease);
}
.card:hover .card__media img { transform: scale(1.03); }
.card:hover .card__media { border-color: var(--fc-rule-strong); }

/*
  No photograph yet. A faint engineering grid with the product's initial reads as a considered
  placeholder rather than a broken image, and keeps the grid's rhythm intact while photography is
  still being shot.
*/
.card__placeholder {
  width: 100%; height: 100%;
  display: grid; place-items: center;
  background-image:
    linear-gradient(var(--fc-rule) 1px, transparent 1px),
    linear-gradient(90deg, var(--fc-rule) 1px, transparent 1px);
  background-size: 16px 16px;
  background-position: -1px -1px;
}
.card__placeholder span {
  font-size: var(--fc-text-3xl); font-weight: 300;
  color: var(--fc-ink-faint); letter-spacing: var(--fc-tracking-tight);
  background: var(--fc-paper-raised); padding: 0 var(--fc-space-3);
}

.card__badges { position: absolute; top: var(--fc-space-3); left: var(--fc-space-3); display: flex; gap: var(--fc-space-2); }

.card__body { display: flex; flex-direction: column; gap: var(--fc-space-2); }

.card__name {
  margin: 0; font-size: var(--fc-text-base); font-weight: 600;
  letter-spacing: var(--fc-tracking-snug); line-height: var(--fc-leading-snug);
}
.card:hover .card__name { text-decoration: underline; text-decoration-color: var(--fc-rule-strong); text-underline-offset: 3px; }

.card__blurb {
  margin: 0; font-size: var(--fc-text-sm); color: var(--fc-ink-muted);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

.card__price { margin: 0; display: flex; align-items: baseline; gap: var(--fc-space-2); font-variant-numeric: tabular-nums; }
.card__from { font-size: var(--fc-text-xs); color: var(--fc-ink-muted); }
.card__amount { font-weight: 600; font-size: var(--fc-text-base); }
.card__was { color: var(--fc-ink-faint); font-size: var(--fc-text-sm); }

.card__meta { display: flex; align-items: center; gap: var(--fc-space-2); font-size: var(--fc-text-xs); color: var(--fc-ink-muted); }
.stars { color: var(--fc-preorder); letter-spacing: 0.06em; }

/* ---------- Product page ---------- */

.breadcrumb {
  display: flex; flex-wrap: wrap; gap: var(--fc-space-2);
  font-size: var(--fc-text-xs); color: var(--fc-ink-muted);
  margin-bottom: var(--fc-space-8);
}
.breadcrumb a { text-decoration: none; }
.breadcrumb a:hover { color: var(--fc-ink); }

.product { display: grid; gap: var(--fc-space-12); grid-template-columns: 1fr; }
@media (min-width: 60rem) {
  .product { grid-template-columns: minmax(0, 1.25fr) minmax(20rem, 0.75fr); gap: var(--fc-space-16); align-items: start; }
}

/* Contain, not cover: show the whole product, zoomed out to fit rather than cropped to fill.
   A little inset so it never touches the frame, and the frame's surface behind the gaps. */
.product__image {
  width: 100%; aspect-ratio: 4 / 5; object-fit: contain;
  padding: 6%;
  border: 1px solid var(--fc-rule); border-radius: var(--fc-radius-lg);
  /* White, not paper: product photos are shot on white, so the frame disappears behind them. */
  background: #fff;
}

/* Squarer than a real photograph would be: a placeholder that fills a tall frame reads as a
   missing image rather than a considered absence. */
.product__gallery .card__placeholder {
  aspect-ratio: 1; border: 1px solid var(--fc-rule); border-radius: var(--fc-radius-lg);
}
.product__thumbs { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--fc-space-2); margin-top: var(--fc-space-3); }
.product__thumbs img { aspect-ratio: 1; object-fit: cover; border: 1px solid var(--fc-rule); border-radius: var(--fc-radius-sm); }

.product__buy { position: sticky; top: calc(64px + var(--fc-space-8)); }
.product__name { margin-bottom: var(--fc-space-3); font-size: clamp(var(--fc-text-2xl), 3.5vw, var(--fc-text-3xl)); }
.product__blurb { color: var(--fc-ink-soft); font-size: var(--fc-text-base); margin-bottom: var(--fc-space-5); }

.product__price {
  display: flex; align-items: baseline; gap: var(--fc-space-3);
  margin: var(--fc-space-6) 0 var(--fc-space-4);
  padding-top: var(--fc-space-6); border-top: 1px solid var(--fc-rule);
  font-variant-numeric: tabular-nums;
}
.product__amount { font-size: var(--fc-text-2xl); font-weight: 600; letter-spacing: var(--fc-tracking-tight); }
.product__was { color: var(--fc-ink-faint); font-size: var(--fc-text-base); }

.product__rating { display: flex; gap: var(--fc-space-2); align-items: center; font-size: var(--fc-text-sm); color: var(--fc-ink-muted); }
.product__story { margin-top: var(--fc-space-24); }
.product__reviews { margin-top: var(--fc-space-24); padding-top: var(--fc-space-12); border-top: 1px solid var(--fc-rule); }

/* ---------- Content blocks ---------- */

.blk { padding-block: var(--fc-space-16); }
.blk--tight { padding-block: var(--fc-space-8); }
.blk--loose { padding-block: var(--fc-space-24); }
.blk--content { max-width: 58rem; margin-inline: auto; }
.blk--wide { max-width: var(--fc-content); margin-inline: auto; }
.blk--full { max-width: none; }

.blk--muted {
  background: var(--fc-paper-raised);
  border: 1px solid var(--fc-rule);
  border-radius: var(--fc-radius-lg);
  padding-inline: clamp(var(--fc-space-6), 5vw, var(--fc-space-16));
  margin-block: var(--fc-space-4);
}
.blk--accent {
  background: var(--fc-accent-tint);
  border: 1px solid color-mix(in srgb, var(--fc-accent) 18%, transparent);
  border-radius: var(--fc-radius-lg);
  padding-inline: clamp(var(--fc-space-6), 5vw, var(--fc-space-16));
}
.blk--dark {
  background: var(--fc-ink); color: #f4f4f5;
  border-radius: var(--fc-radius-lg);
  padding-inline: clamp(var(--fc-space-6), 5vw, var(--fc-space-16));
}
.blk--dark :where(p, li) { color: #b8b8c0; }

/* Entrance animation, added by reveal.js.

   The revealed rule repeats the whole hiding selector on purpose. Written as the shorter
   `.blk.is-visible` it scores (0,2,0) against the hiding rule's (0,3,0) and loses on specificity,
   so blocks would fade in and never arrive. */
@media (prefers-reduced-motion: no-preference) {
  .blk[data-reveal]:not([data-reveal="none"]) {
    opacity: 0;
    transition: opacity 600ms var(--fc-ease), transform 600ms var(--fc-ease);
  }
  .blk[data-reveal="fade-up"]:not(.is-visible) { transform: translateY(20px); }
  .blk[data-reveal]:not([data-reveal="none"]).is-visible { opacity: 1; transform: none; }
}

.blk__prose { max-width: var(--fc-prose); }

/*
  An authored description brings its own layout, so it is not held to a reading measure - a
  design built at 1080px was being squeezed into 672 and losing its own padding at the edges.
  Text written as plain paragraphs still gets the measure, because a line that runs the whole
  width of a page is no easier to read here than anywhere else.
*/
.blk__prose--authored { max-width: none; }
.blk__prose--authored > :where(p, ul, ol, blockquote, h1, h2, h3, h4) {
  max-width: var(--fc-prose);
}
.blk__prose :where(p, li) { color: var(--fc-ink-soft); }
.blk__divider { border: 0; border-top: 1px solid var(--fc-rule); margin: 0; }

.hero { text-align: center; max-width: 46rem; margin-inline: auto; }
.hero__eyebrow {
  font-size: var(--fc-text-2xs); font-weight: 650;
  letter-spacing: var(--fc-tracking-wide); text-transform: uppercase;
  color: var(--fc-accent); margin-bottom: var(--fc-space-4);
}
.hero__headline { font-size: clamp(var(--fc-text-3xl), 6vw, var(--fc-text-5xl)); margin-bottom: var(--fc-space-5); }
.hero__subhead { font-size: var(--fc-text-lg); color: var(--fc-ink-soft); max-width: 38rem; margin-inline: auto; }
.hero__actions { display: flex; gap: var(--fc-space-3); justify-content: center; margin-top: var(--fc-space-8); flex-wrap: wrap; }
.hero__media { border-radius: var(--fc-radius-lg); border: 1px solid var(--fc-rule); margin-top: var(--fc-space-12); }

.feature { display: grid; gap: var(--fc-space-10); align-items: center; }
@media (min-width: 52rem) {
  .feature { grid-template-columns: 1fr 1fr; gap: var(--fc-space-16); }
  .blk--invert .feature__media { order: -1; }
}
/* No image means no second column; otherwise the copy is squeezed into half the width for no
   reason and the other half sits empty. */
.feature--textonly { grid-template-columns: 1fr; max-width: var(--fc-prose); }

.feature__title { margin-bottom: var(--fc-space-2); }
.feature__caption {
  color: var(--fc-accent); font-size: var(--fc-text-xs); font-weight: 650;
  letter-spacing: var(--fc-tracking-wide); text-transform: uppercase;
  margin-bottom: var(--fc-space-4);
}
.feature__bullets { padding-left: 0; list-style: none; margin: var(--fc-space-4) 0 0; }
.feature__bullets li {
  position: relative; padding-left: var(--fc-space-5);
  color: var(--fc-ink-soft); font-size: var(--fc-text-sm); margin-bottom: var(--fc-space-2);
}
.feature__bullets li::before {
  content: ""; position: absolute; left: 0; top: 0.6em;
  width: 8px; height: 1px; background: var(--fc-accent);
}
.feature__media img { border-radius: var(--fc-radius-md); border: 1px solid var(--fc-rule); }

/* Technical data. Tabular numerals and a monospace value column so figures line up the way a
   spec sheet should. */
.specs__title, .compare__title, .gallery__title, .faq__title { margin-bottom: var(--fc-space-6); }
.specs__group {
  font-size: var(--fc-text-2xs); font-weight: 650; text-transform: uppercase;
  letter-spacing: var(--fc-tracking-wide); color: var(--fc-ink-muted);
  margin: var(--fc-space-8) 0 var(--fc-space-2);
}
.specs__table, .compare__table { width: 100%; border-collapse: collapse; font-size: var(--fc-text-sm); }
.specs__table th, .specs__table td,
.compare__table th, .compare__table td {
  text-align: left; padding: var(--fc-space-3) var(--fc-space-4);
  border-bottom: 1px solid var(--fc-rule); vertical-align: top;
}
.specs__table th { width: 40%; font-weight: 500; color: var(--fc-ink-muted); }
.specs__table td { font-family: var(--fc-font-mono); font-size: var(--fc-text-xs); font-variant-numeric: tabular-nums; }
.specs__note { display: block; font-family: var(--fc-font-sans); color: var(--fc-ink-muted); font-size: var(--fc-text-xs); margin-top: 2px; }

.compare__table thead th {
  font-size: var(--fc-text-2xs); font-weight: 650; text-transform: uppercase;
  letter-spacing: var(--fc-tracking-wide); color: var(--fc-ink-muted);
  border-bottom-color: var(--fc-rule-strong);
}
.compare__table tbody th { font-weight: 500; }
.compare__table td { font-variant-numeric: tabular-nums; }
/* The last column is the paid edition; tinting it makes the comparison read at a glance. */
.compare__table :where(td, thead th):last-child { background: var(--fc-accent-tint); }

.gallery__grid { display: grid; gap: var(--fc-space-4); grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
.gallery__item { margin: 0; }
.gallery__item img { border-radius: var(--fc-radius-md); border: 1px solid var(--fc-rule); }
.gallery__item figcaption { font-size: var(--fc-text-xs); color: var(--fc-ink-muted); margin-top: var(--fc-space-2); }

.faq__item { border-bottom: 1px solid var(--fc-rule); }
.faq__item summary {
  cursor: pointer; padding: var(--fc-space-4) 0;
  font-weight: 550; font-size: var(--fc-text-base);
  list-style: none; display: flex; justify-content: space-between; align-items: center; gap: var(--fc-space-4);
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__item summary::after {
  content: "+"; color: var(--fc-ink-muted); font-weight: 400; font-size: var(--fc-text-lg);
  transition: transform 200ms var(--fc-ease);
}
.faq__item[open] summary::after { transform: rotate(45deg); }
.faq__item .blk__prose { padding-bottom: var(--fc-space-4); }

.cta { text-align: center; max-width: 40rem; margin-inline: auto; }
.cta__headline { margin-bottom: var(--fc-space-3); }
.cta__body { color: var(--fc-ink-soft); margin-bottom: var(--fc-space-6); }

.video__player { width: 100%; border-radius: var(--fc-radius-lg); border: 1px solid var(--fc-rule); }

/* ---------- Cart ---------- */

.cart { display: grid; gap: var(--fc-space-12); grid-template-columns: 1fr; align-items: start; }
@media (min-width: 56rem) { .cart { grid-template-columns: minmax(0, 1fr) 21rem; } }

.cart__lines { list-style: none; padding: 0; margin: 0; border-top: 1px solid var(--fc-rule); }
.cart-line {
  display: grid; grid-template-columns: 4.5rem 1fr auto auto;
  gap: var(--fc-space-4); align-items: center;
  padding: var(--fc-space-5) 0; border-bottom: 1px solid var(--fc-rule);
}
.cart-line__image { width: 4.5rem; aspect-ratio: 4/5; object-fit: cover; border: 1px solid var(--fc-rule); border-radius: var(--fc-radius-sm); }
.cart-line__detail { display: flex; flex-direction: column; gap: var(--fc-space-1); min-width: 0; }
.cart-line__detail a { font-weight: 550; text-decoration: none; }
.cart-line__variant { color: var(--fc-ink-muted); font-size: var(--fc-text-sm); }

/* What was chosen, on its own line: it is what distinguishes two otherwise identical lines. */
.cart-line__option {
  display: block; font-size: var(--fc-text-sm); color: var(--fc-ink-soft);
}
.cart-line__total { font-weight: 600; font-variant-numeric: tabular-nums; }

.cart__summary {
  border: 1px solid var(--fc-rule); border-radius: var(--fc-radius-lg);
  padding: var(--fc-space-6); background: var(--fc-paper-raised);
}
.totals { display: grid; grid-template-columns: 1fr auto; gap: var(--fc-space-3) var(--fc-space-4); margin: var(--fc-space-6) 0; font-variant-numeric: tabular-nums; }
.totals dt { color: var(--fc-ink-muted); font-size: var(--fc-text-sm); }
.totals dd { margin: 0; text-align: right; font-size: var(--fc-text-sm); }
.totals__grand { font-weight: 650; font-size: var(--fc-text-lg) !important; color: var(--fc-ink); padding-top: var(--fc-space-3); border-top: 1px solid var(--fc-rule); }

/* ---------- Reviews ---------- */

.reviews { list-style: none; padding: 0; margin: 0; }
.review { padding: var(--fc-space-6) 0; border-bottom: 1px solid var(--fc-rule); }
.review__head { display: flex; gap: var(--fc-space-3); align-items: center; flex-wrap: wrap; font-size: var(--fc-text-sm); margin-bottom: var(--fc-space-2); }
.review__head time { color: var(--fc-ink-muted); font-size: var(--fc-text-xs); }
.review__title { font-size: var(--fc-text-base); margin-bottom: var(--fc-space-2); }
.review__body { color: var(--fc-ink-soft); }
.review__reply { margin-top: var(--fc-space-3); padding: var(--fc-space-4); background: var(--fc-paper-raised); border-radius: var(--fc-radius-sm); font-size: var(--fc-text-sm); }
.review-form { margin-top: var(--fc-space-8); }
.review-form summary { cursor: pointer; font-weight: 550; font-size: var(--fc-text-sm); }

/* ---------- Account ----------
   A sign-in form stretched across the full content width is hard to scan and looks unfinished.
   These pages get their own narrow measure. */

.auth { max-width: 24rem; margin: var(--fc-space-8) auto var(--fc-space-16); }
.auth h1 { font-size: var(--fc-text-2xl); margin-bottom: var(--fc-space-2); }
.auth__intro { color: var(--fc-ink-muted); font-size: var(--fc-text-sm); margin-bottom: var(--fc-space-8); }
.auth__links { margin-top: var(--fc-space-6); font-size: var(--fc-text-sm); color: var(--fc-ink-muted); }
.auth__links a { text-decoration-color: var(--fc-rule-strong); }
.auth .btn--primary { width: 100%; margin-top: var(--fc-space-2); }
.auth .field--inline { align-items: center; gap: var(--fc-space-2); }
.auth .field--inline label { margin: 0; text-transform: none; letter-spacing: 0; font-size: var(--fc-text-sm); font-weight: 400; color: var(--fc-ink); }

.denied { max-width: 30rem; margin: var(--fc-space-20) auto; text-align: center; }
.denied__mark { width: 48px; height: 48px; color: var(--fc-ink-faint); margin-bottom: var(--fc-space-6); }
.denied h1 { font-size: var(--fc-text-2xl); margin-bottom: var(--fc-space-4); }
.denied__body { color: var(--fc-ink-muted); }
.denied__actions { display: flex; gap: var(--fc-space-3); justify-content: center; margin-top: var(--fc-space-8); flex-wrap: wrap; }
.denied__actions form { margin: 0; }

/* ---------- Account area ---------- */

.account { display: grid; gap: var(--fc-space-10); grid-template-columns: 1fr; align-items: start; }
@media (min-width: 52rem) { .account { grid-template-columns: 12rem minmax(0, 1fr); gap: var(--fc-space-16); } }

.account__nav { display: flex; flex-direction: column; gap: var(--fc-space-1); }
.account__link {
  padding: var(--fc-space-2) var(--fc-space-3);
  border-radius: var(--fc-radius-sm);
  font-size: var(--fc-text-sm); color: var(--fc-ink-muted); text-decoration: none;
}
.account__link:hover { background: var(--fc-paper-raised); color: var(--fc-ink); }
.account__link.active { background: var(--fc-paper-sunken); color: var(--fc-ink); font-weight: 550; }
.account__signout { margin-top: var(--fc-space-4); padding-top: var(--fc-space-4); border-top: 1px solid var(--fc-rule); }
.account__body { min-width: 0; }
.account__body h1 { font-size: var(--fc-text-2xl); }
.account__body h2 { font-size: var(--fc-text-lg); margin-top: var(--fc-space-12); }
.account__body h2:first-of-type { margin-top: var(--fc-space-8); }
.account__body form { max-width: 28rem; }

.grid-2 { display: grid; gap: var(--fc-space-4); grid-template-columns: 1fr 1fr; }
.grid-3 { display: grid; gap: var(--fc-space-4); grid-template-columns: 2fr 1fr 1fr; }

.address-list { list-style: none; padding: 0; margin: 0 0 var(--fc-space-8); display: grid; gap: var(--fc-space-4); grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr)); }
.address-card {
  border: 1px solid var(--fc-rule); border-radius: var(--fc-radius-md);
  padding: var(--fc-space-4); font-size: var(--fc-text-sm);
  display: flex; flex-direction: column; justify-content: space-between; gap: var(--fc-space-3);
}
.address-card__actions { display: flex; gap: var(--fc-space-3); align-items: center; flex-wrap: wrap; }
.address-card__actions form { margin: 0; }

/* Sized so it scans reliably from a phone held at arm's length without dominating the page. */
.qr { width: 180px; margin: var(--fc-space-4) 0; }
.qr svg { width: 100%; height: auto; display: block; border: 1px solid var(--fc-rule); border-radius: var(--fc-radius-sm); }

.recovery { list-style: none; padding: 0; margin: var(--fc-space-3) 0 0; display: grid; gap: var(--fc-space-1); grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); }
.recovery li { font-size: var(--fc-text-sm); }

.btn--danger { color: var(--fc-sale); }

/* ---------- Odds and ends ---------- */

.empty { color: var(--fc-ink-muted); padding: var(--fc-space-12) 0; }
/* The field takes the room; the button takes what it needs.
   Without flex-grow the input keeps its intrinsic width inside a flex row and ends up barely wider
   than its placeholder. min-width:0 lets it shrink below that intrinsic width on a small screen
   instead of pushing the button off the edge. */
.search {
  display: flex;
  gap: var(--fc-space-2);
  max-width: 34rem;
  margin-bottom: var(--fc-space-8);
}
.search .input {
  flex: 1 1 auto;
  min-width: 0;
  padding-block: var(--fc-space-3);
  font-size: var(--fc-text-base);
}
.search .btn { flex: 0 0 auto; }

/* On a phone the button drops beneath a full-width field rather than squeezing both onto one row. */
@media (max-width: 30rem) {
  .search { flex-direction: column; align-items: stretch; }
}
.search__count { color: var(--fc-ink-muted); font-size: var(--fc-text-sm); margin-bottom: var(--fc-space-6); }
.category__intro { max-width: var(--fc-prose); color: var(--fc-ink-soft); font-size: var(--fc-text-lg); margin-bottom: var(--fc-space-10); }

.table { width: 100%; border-collapse: collapse; font-size: var(--fc-text-sm); }
.table th, .table td { text-align: left; padding: var(--fc-space-3) var(--fc-space-4); border-bottom: 1px solid var(--fc-rule); }
.table th { font-size: var(--fc-text-2xs); text-transform: uppercase; letter-spacing: var(--fc-tracking-wide); color: var(--fc-ink-muted); }
.table .num { text-align: right; font-variant-numeric: tabular-nums; }
.mono { font-family: var(--fc-font-mono); font-size: var(--fc-text-xs); }
.muted { color: var(--fc-ink-muted); }

/* ---------------------------------------------------------------------------
   Checkout

   Two columns on a desk, one on a phone, with the summary above the form so the
   total is the first thing seen rather than something to scroll for.
   --------------------------------------------------------------------------- */

.checkout {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: var(--fc-space-8, 2rem);
  align-items: start;
  margin-bottom: var(--fc-space-12, 3rem);
}

.checkout__step {
  padding: var(--fc-space-6, 1.5rem);
  margin-bottom: var(--fc-space-5, 1.25rem);
  background: var(--fc-paper);
  border: 1px solid var(--fc-rule);
  border-radius: var(--fc-radius-lg);
}
.checkout__step h2 {
  margin: 0 0 var(--fc-space-4, 1rem);
  font-size: var(--fc-text-lg);
  letter-spacing: var(--fc-tracking-snug);
}
.checkout__hint { margin: var(--fc-space-2, 0.5rem) 0 0; font-size: var(--fc-text-sm); color: var(--fc-ink-muted); }

.checkout .field { display: flex; flex-direction: column; gap: 5px; margin-bottom: var(--fc-space-4, 1rem); flex: 1 1 12rem; }
.checkout .field label { font-size: var(--fc-text-xs); font-weight: 600; color: var(--fc-ink-soft); }
.checkout .field--narrow { flex: 0 1 8rem; }
.checkout .field-row { display: flex; flex-wrap: wrap; gap: var(--fc-space-4, 1rem); }

.checkout .input {
  width: 100%; padding: 0.65rem 0.75rem;
  font: inherit; font-size: var(--fc-text-base);
  color: var(--fc-ink); background: var(--fc-paper);
  border: 1px solid var(--fc-rule); border-radius: var(--fc-radius-sm);
}
.checkout .input:focus-visible {
  outline: 2px solid var(--fc-accent); outline-offset: 1px; border-color: var(--fc-accent);
}

.rates { display: grid; gap: var(--fc-space-2, 0.5rem); }
.rate {
  display: flex; align-items: center; gap: var(--fc-space-3, 0.75rem);
  padding: 0.75rem 0.9rem; cursor: pointer;
  border: 1px solid var(--fc-rule); border-radius: var(--fc-radius-sm);
}
.rate:hover { border-color: var(--fc-ink-faint); }
/* :has lets the whole row show selection without scripting it. */
.rate:has(input:checked) { border-color: var(--fc-accent); background: var(--fc-accent-tint); }
.rate__name { flex: 1; font-weight: 500; }
.rate__eta { font-size: var(--fc-text-sm); color: var(--fc-ink-muted); }
.rate__price { font-variant-numeric: tabular-nums; font-weight: 600; }

.checkout__error {
  padding: 0.75rem 0.9rem; margin: 0 0 var(--fc-space-4, 1rem);
  border-radius: var(--fc-radius-sm);
  background: #fdecea; color: #a32b1c; font-size: var(--fc-text-sm);
}

.checkout__summary {
  position: sticky; top: var(--fc-space-6, 1.5rem);
  padding: var(--fc-space-6, 1.5rem);
  background: var(--fc-paper-raised);
  border-radius: var(--fc-radius-lg);
}
.checkout__summary h2 { margin: 0 0 var(--fc-space-4, 1rem); font-size: var(--fc-text-base); }
.checkout__lines { list-style: none; margin: 0 0 var(--fc-space-4, 1rem); padding: 0; }
.checkout__lines li {
  display: flex; gap: var(--fc-space-3, 0.75rem); padding: 0.4rem 0;
  font-size: var(--fc-text-sm);
}
.checkout__qty { color: var(--fc-ink-muted); font-variant-numeric: tabular-nums; }
.checkout__name { flex: 1; }
.checkout__money { font-variant-numeric: tabular-nums; }

.checkout__totals {
  display: grid; grid-template-columns: 1fr auto; gap: 0.4rem var(--fc-space-4, 1rem);
  margin: 0; padding-top: var(--fc-space-4, 1rem);
  border-top: 1px solid var(--fc-rule); font-size: var(--fc-text-sm);
}
.checkout__totals dt { color: var(--fc-ink-soft); }
.checkout__totals dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.checkout__grand { font-size: var(--fc-text-lg); font-weight: 650; color: var(--fc-ink); }

.checkout__back {
  display: inline-block; margin-top: var(--fc-space-4, 1rem);
  font-size: var(--fc-text-sm); color: var(--fc-ink-muted);
}

#paypal-buttons { min-height: 3rem; }

/* ---- Confirmation ---- */

.confirmation { max-width: 46rem; margin-bottom: var(--fc-space-12, 3rem); }
.confirmation__badge {
  margin: 0; font-size: var(--fc-text-2xs); font-weight: 700;
  letter-spacing: var(--fc-tracking-wide); text-transform: uppercase; color: var(--fc-accent);
}
.confirmation h1 { margin: var(--fc-space-2, 0.5rem) 0 var(--fc-space-4, 1rem); }
.confirmation__lede { font-size: var(--fc-text-lg); color: var(--fc-ink-soft); }
.confirmation__panel {
  padding: var(--fc-space-6, 1.5rem); margin: var(--fc-space-6, 1.5rem) 0;
  background: var(--fc-paper); border: 1px solid var(--fc-rule); border-radius: var(--fc-radius-lg);
}
.confirmation__panel h2 { margin: 0 0 var(--fc-space-4, 1rem); font-size: var(--fc-text-base); }
.confirmation__lines { list-style: none; margin: 0 0 var(--fc-space-4, 1rem); padding: 0; }
.confirmation__lines li { display: flex; gap: var(--fc-space-3, 0.75rem); padding: 0.4rem 0; }
.confirmation__qty { color: var(--fc-ink-muted); font-variant-numeric: tabular-nums; }
.confirmation__name { flex: 1; }
.confirmation__money { font-variant-numeric: tabular-nums; }
.confirmation__totals {
  display: grid; grid-template-columns: 1fr auto; gap: 0.4rem var(--fc-space-4, 1rem);
  margin: 0; padding-top: var(--fc-space-4, 1rem); border-top: 1px solid var(--fc-rule);
}
.confirmation__totals dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.confirmation__downloads { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }

@media (max-width: 60rem) {
  .checkout { grid-template-columns: 1fr; }
  /* Summary first on a phone: the total should not be something to scroll for. */
  .checkout__summary { position: static; order: -1; }
}

.fc-footer__links {
  display: flex; gap: var(--fc-space-5, 1.25rem); align-items: center;
  font-size: var(--fc-text-sm);
}
.fc-footer__links a { color: var(--fc-ink-soft); }

.lookup { max-width: 30rem; margin-bottom: var(--fc-space-12, 3rem); }
.lookup__lede { color: var(--fc-ink-soft); }
.lookup .field { display: flex; flex-direction: column; gap: 5px; margin-bottom: var(--fc-space-4, 1rem); }
.lookup .field label { font-size: var(--fc-text-xs); font-weight: 600; color: var(--fc-ink-soft); }
.lookup .input {
  width: 100%; padding: 0.65rem 0.75rem; font: inherit; font-size: var(--fc-text-base);
  border: 1px solid var(--fc-rule); border-radius: var(--fc-radius-sm);
  color: var(--fc-ink); background: var(--fc-paper);
}
.lookup .input:focus-visible {
  outline: 2px solid var(--fc-accent); outline-offset: 1px; border-color: var(--fc-accent);
}
.lookup__alt { margin-top: var(--fc-space-6, 1.5rem); font-size: var(--fc-text-sm); color: var(--fc-ink-muted); }

@media (max-width: 46rem) {
  .fc-footer__links { justify-content: center; }
}

/* The gallery strip: a row of links, the current one marked. */
.product__thumb {
  display: block; padding: 0; border: 2px solid transparent; border-radius: var(--fc-radius-sm);
  background: var(--fc-paper-raised); overflow: hidden; line-height: 0;
}
.product__thumb img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; display: block; }
.product__thumb:hover { border-color: var(--fc-rule); }
.product__thumb.is-current { border-color: var(--fc-accent); }
.product__thumb:focus-visible { outline: 2px solid var(--fc-accent); outline-offset: 2px; }

/* Video embeds in authored prose.
   The migrated descriptions sized their videos with inline styles, which the sanitiser removes,
   so the shape is set here instead - and it is responsive, which the originals were not. */
.blk__prose iframe,
.product__blurb iframe {
  display: block; width: 100%; height: auto; aspect-ratio: 16 / 9;
  max-width: 100%; border: 0; border-radius: var(--fc-radius-md);
}
.blk__prose img, .product__blurb img { max-width: 100%; height: auto; }

/* ---------------------------------------------------------------------------
   When something goes wrong

   Calm rather than alarming. The number is large but faint - it is there for
   whoever needs it and out of the way for everyone else - and the way onward is
   the loudest thing on the page.
   --------------------------------------------------------------------------- */

.mishap {
  max-width: 34rem;
  margin: clamp(3rem, 12vh, 7rem) auto clamp(4rem, 14vh, 8rem);
  text-align: center;
}

.mishap__code {
  margin: 0;
  font-size: clamp(4.5rem, 18vw, 8rem);
  font-weight: 700;
  line-height: 0.9;
  letter-spacing: var(--fc-tracking-tight);
  color: var(--fc-accent);
  /* A watermark, not a headline: the words below are what the visitor reads. */
  opacity: 0.14;
  user-select: none;
}

.mishap__title {
  /* Tucked just under the numeral rather than through it: they overlap enough to read as one
     unit, not so much that the digits are struck out. */
  margin: clamp(-1.4rem, -3vw, -0.8rem) 0 var(--fc-space-4, 1rem);
  font-size: var(--fc-text-2xl);
  letter-spacing: var(--fc-tracking-tight);
}

.mishap__line {
  margin: 0 0 var(--fc-space-3, 0.75rem);
  font-size: var(--fc-text-lg);
  color: var(--fc-ink-soft);
}

.mishap__aside {
  margin: 0 auto var(--fc-space-7, 1.75rem);
  max-width: 28rem;
  color: var(--fc-ink-muted);
  line-height: var(--fc-leading-normal);
}

.mishap__actions {
  display: flex; flex-wrap: wrap; gap: var(--fc-space-3, 0.75rem); justify-content: center;
}

.mishap__id {
  margin: var(--fc-space-8, 2rem) 0 0;
  font-size: var(--fc-text-sm);
  color: var(--fc-ink-faint);
}
.mishap__id code {
  display: inline-block;
  font-family: var(--fc-font-mono); font-size: var(--fc-text-xs);
  padding: 2px 6px; border-radius: var(--fc-radius-xs); background: var(--fc-paper-sunken);
  color: var(--fc-ink-soft);
  /* Never split across lines: half a request id is no use to anyone reading it back. */
  white-space: nowrap;
}

.mishap__detail {
  margin-top: var(--fc-space-8, 2rem); text-align: left;
  border: 1px solid var(--fc-rule); border-radius: var(--fc-radius-md);
  background: var(--fc-paper-raised);
}
.mishap__detail summary {
  padding: 0.7rem 0.9rem; cursor: pointer;
  font-size: var(--fc-text-sm); color: var(--fc-ink-soft);
}
.mishap__detail pre {
  margin: 0; padding: 0.9rem; max-height: 22rem; overflow: auto;
  font-family: var(--fc-font-mono); font-size: var(--fc-text-xs); line-height: 1.55;
  white-space: pre-wrap; word-break: break-word; color: var(--fc-ink-soft);
  border-top: 1px solid var(--fc-rule);
}

/* A product that is kept for reference but can no longer be bought. */
.product__retired-tag { color: var(--fc-ink-muted); font-weight: 500; }
.product__retired {
  padding: var(--fc-space-5, 1.25rem);
  border: 1px solid var(--fc-rule);
  border-radius: var(--fc-radius, 10px);
  background: var(--fc-surface-sunken, #f6f6f4);
}
.product__retired-lead { margin: 0 0 var(--fc-space-2, 0.5rem); font-weight: 650; }
.product__retired p { margin: 0 0 var(--fc-space-3, 0.75rem); }
/* This is the one button whose label can be arbitrarily long - a whole product name - so it
   wraps and is bounded to its box rather than forcing a line wider than the phone it is read on.
   Every other button keeps the default nowrap. */
.product__retired .btn {
  margin-top: var(--fc-space-1, 0.25rem);
  white-space: normal;
  max-width: 100%;
  height: auto;
  min-height: 2.5rem;
  padding-block: var(--fc-space-2, 0.5rem);
  text-align: center;
}


/* ---------- Add-ons ---------- */

/*
  Extras offered beside a product. Set apart from the product's own choices by a rule and a
  heading, because these are separate things being bought rather than a decision about this one -
  a customer who does not read the difference ends up surprised by their basket.
*/
.addons {
  border: 0; border-top: 1px solid var(--fc-rule);
  margin: var(--fc-space-4) 0 0; padding: var(--fc-space-4) 0 0;
}

.addons__legend {
  padding: 0; font-size: var(--fc-text-xs); font-weight: 650;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--fc-ink-muted);
}

.addon {
  display: flex; align-items: center; gap: var(--fc-space-3);
  padding: var(--fc-space-3) 0;
  border-bottom: 1px solid var(--fc-rule-soft, var(--fc-rule));
}
/* The checkbox and the label parts (variant, note, price) toggle the add-on; the
   name is a link to the add-on's own page, so it does not. */
.addon input[type="checkbox"], .addon__variant, .addon__note, .addon__price { cursor: pointer; }
.addon--out .addon__variant, .addon--out .addon__note, .addon--out .addon__price { cursor: default; }
.addon:last-child { border-bottom: 0; }

.addon__body { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.addon__name { font-weight: 550; color: inherit; text-decoration: none; align-self: flex-start; cursor: pointer; }
.addon__name:hover { text-decoration: underline; }
.addon--out .addon__name:hover { text-decoration: none; }
.addon__variant { font-size: var(--fc-text-sm); color: var(--fc-ink-muted); }
.addon__note { font-size: var(--fc-text-sm); color: var(--fc-ink-muted); line-height: 1.45; margin-top: 1px; }
.addon__price { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Shown and disabled rather than hidden: someone who came for it deserves to be told it is out
   of stock, not left wondering whether it stopped being made. */
.addon--out { cursor: default; color: var(--fc-ink-muted); }
.addon--out .addon__name { font-weight: 500; }
.addon__out {
  font-size: var(--fc-text-xs); font-weight: 650;
  letter-spacing: 0.03em; text-transform: uppercase; color: var(--fc-out);
}
