/* =====================================================================
   Oblifee marketing theme — "the receipt"

   WHY THIS FILE EXISTS. The site described a category, and the product
   is a position inside it. Every regulatory intelligence site says the
   same seven things, so saying them slightly better reads as flat no
   matter how it is styled. The one thing here that a competitor cannot
   copy without doing the work first is the receipt: a source, a date it
   was read, and how sure we are. So the receipt IS the design language
   rather than a detail inside it.

   Three rules hold the whole file together.

     1. A number never appears without its provenance. `.receipt` is the
        smallest component in the system and the most used.
     2. Status colour is structural, never decorative. Leaf is confirmed,
        Pollen is illustrative, Coral is an estimate. Those three carry
        that exact meaning inside the product, so they must not be spent
        on anything else out here.
     3. Every page states its problem and its answer in the same place,
        in the same two typographic weights, so the rhythm is learned by
        the third page and the reader always knows where to look.

   Loaded AFTER oblifee.css and site.css, so it can restyle the kit's
   classes in place. Existing markup gets the new look without being
   rewritten; new markup uses the components below.
   ===================================================================== */

/* ------------------------------------------------------------ tokens */
.ob-root, :root {
  /* Grounds. Kelp carries the openers, Mist the working sections. The
     site alternates between them so scrolling has a pulse instead of
     being one continuous pale field. */
  --t-deep: #04120F;
  --t-kelp: #0A2E28;
  --t-kelp-2: #0F3B31;
  --t-mist: #F5FAF7;
  --t-paper: #FFFFFF;

  --t-ink: #0A2E28;
  --t-ink-2: #4A6B61;
  --t-ink-3: #7B9A91;
  --t-line: #DCEAE2;

  --t-on-deep: #EAF6EF;
  --t-on-deep-2: #9FC4B6;
  --t-on-deep-3: #6E8F83;
  --t-line-deep: rgba(255, 255, 255, .14);

  --t-leaf: #00C878;
  --t-leaf-bright: #0FE28C;
  --t-leaf-deep: #00854F;
  --t-pollen: #FFC24B;
  --t-coral: #FF6A5A;
  --t-bridge: #2FC8C2;

  /* The third face. The site had a display and a body face and nothing
     that reads as measurement, which is most of why data on it looked
     like copy. System mono only: font-src is 'self' and no mono is
     bundled, so a web font here would silently fall back anyway. */
  --t-mono: ui-monospace, 'SF Mono', SFMono-Regular, 'Cascadia Mono',
            'Segoe UI Mono', Menlo, Consolas, monospace;

  --t-ease: cubic-bezier(.22, .7, .3, 1);
}

/* ------------------------------------------------------- page rhythm */
/* Wider than the kit's 1080. The homepage needs room for an asymmetric
   grid; a centred 1080 column is most of why every section read the
   same as the last one. */
.ob-container { max-width: 1200px; }
.t-wide .ob-container, .ob-container.t-wide { max-width: 1340px; }

.t-band { position: relative; padding: clamp(72px, 9vw, 132px) 0; }
.t-band + .t-band { padding-top: clamp(56px, 7vw, 104px); }
.t-band.t-tight { padding: clamp(48px, 6vw, 84px) 0; }

/* dark bands invert the whole token set, so anything inside them —
   kit components included — comes right without per-element overrides */
.t-dark {
  background: var(--t-kelp);
  --ob-ground: var(--t-kelp); --ob-card: rgba(255, 255, 255, .045);
  --ob-ink: var(--t-on-deep); --ob-ink-2: var(--t-on-deep-2);
  --ob-line: var(--t-line-deep); --ob-accent-ink: var(--t-leaf-bright);
  --t-ink: var(--t-on-deep); --t-ink-2: var(--t-on-deep-2);
  --t-ink-3: var(--t-on-deep-3); --t-line: var(--t-line-deep);
  --t-paper: rgba(255, 255, 255, .045);
  color: var(--t-on-deep);
}
.t-dark h1, .t-dark h2, .t-dark h3, .t-dark h4, .t-dark .ob-h3 { color: var(--t-on-deep); }
.t-deep { background: radial-gradient(1200px 760px at 74% -18%, var(--t-kelp-2), var(--t-deep) 68%); }
.t-paper { background: var(--t-paper); }
.t-mist { background: var(--t-mist); }

/* A hairline grid behind the dark bands. It is the only ornament in the
   theme and it is doing a job: it reads as graph paper, which is what
   an instrument sits on. */
.t-grid::before {
  content: ''; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background-image:
    linear-gradient(rgba(255, 255, 255, .05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .05) 1px, transparent 1px);
  background-size: 76px 76px;
  -webkit-mask-image: radial-gradient(900px 520px at 50% 0, #000, transparent 78%);
  mask-image: radial-gradient(900px 520px at 50% 0, #000, transparent 78%);
}
.t-band > .ob-container { position: relative; z-index: 1; }

/* ------------------------------------------------------------- type */
.t-display {
  font-family: var(--ob-font-display);
  font-weight: 800; line-height: .98; letter-spacing: -.028em;
  font-size: clamp(2.6rem, 1.4rem + 4.6vw, 5.6rem);
  text-wrap: balance; margin: 0;
}
.t-display .thin { font-weight: 600; color: var(--t-ink-2); }

/* The homepage headline, one step down from the full display size.
   NOTE: do not set this inline. site.js rewrites the style attribute of
   every reveal element to add a transition delay, and an inline
   font-size is lost the moment it does. */
.t-display.t-hero { font-size: clamp(2.3rem, 1.3rem + 2.2vw, 3.4rem); max-width: 16ch; }

.t-display em { font-style: normal; color: var(--t-leaf); }
.t-dark .t-display em { color: var(--t-leaf-bright); }

.t-h2 {
  font-family: var(--ob-font-display); font-weight: 800;
  font-size: clamp(1.9rem, 1.2rem + 2.2vw, 3.1rem);
  line-height: 1.04; letter-spacing: -.022em; text-wrap: balance;
  margin: 0; max-width: 22ch;
}
.t-h3 { font-family: var(--ob-font-display); font-weight: 800;
  font-size: clamp(1.12rem, 1rem + .42vw, 1.42rem); line-height: 1.18;
  letter-spacing: -.014em; margin: 0; }

.t-lead { font-size: clamp(1.06rem, .96rem + .56vw, 1.36rem);
  line-height: 1.5; color: var(--t-ink-2); max-width: 58ch; margin: 0; }
.t-note { font-size: .92rem; line-height: 1.55; color: var(--t-ink-2); max-width: 76ch; }

.t-eyebrow { font-family: var(--t-mono); font-size: .74rem; font-weight: 600;
  letter-spacing: .18em; text-transform: uppercase; color: var(--t-leaf-deep);
  margin: 0 0 14px; display: block; }
.t-dark .t-eyebrow { color: var(--t-leaf-bright); }

/* ----------------------------------------------- the problem/answer */
/* The spine of the site. Every page opens with one of these, in the
   same position, so a reader learns where the point is. The problem is
   set in the display face because it is the thing they already feel;
   the answer is set smaller and marked, because an answer that shouts
   louder than the problem reads as a claim. */
.t-pa { display: grid; gap: 26px; }
.t-pa .t-problem { display: block; }
.t-pa .t-answer {
  display: grid; grid-template-columns: auto 1fr; gap: 16px;
  align-items: start; max-width: 60ch;
}
.t-pa .t-answer::before {
  content: ''; width: 3px; border-radius: 2px; align-self: stretch;
  background: linear-gradient(180deg, var(--t-leaf), var(--t-bridge));
}
.t-pa .t-answer p { margin: 0; font-size: clamp(1.02rem, .94rem + .5vw, 1.28rem);
  line-height: 1.48; color: var(--t-ink); font-weight: 500; }
.t-dark .t-pa .t-answer p { color: var(--t-on-deep); }

/* ---------------------------------------------------------- receipt */
/* The smallest component in the system and the reason the rest of it
   holds together. Wherever a figure appears, this sits under it. */
.receipt { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-family: var(--t-mono); font-size: .72rem; line-height: 1.4;
  color: var(--t-ink-3); letter-spacing: .01em; }
.receipt a { color: inherit; text-decoration: underline;
  text-underline-offset: 2px; text-decoration-thickness: 1px; }
.receipt a:hover { color: var(--t-leaf-deep); }
.t-dark .receipt a:hover { color: var(--t-leaf-bright); }
.receipt .sep { opacity: .45; }
.receipt .dot { width: 7px; height: 7px; border-radius: 50%; flex: none;
  background: var(--t-leaf); box-shadow: 0 0 0 3px rgba(0, 200, 120, .16); }
.receipt .dot.illustrative { background: var(--t-pollen); box-shadow: 0 0 0 3px rgba(255, 194, 75, .18); }
.receipt .dot.estimate { background: var(--t-coral); box-shadow: 0 0 0 3px rgba(255, 106, 90, .18); }

/* a status word, where the dot alone is not enough */
.t-status { font-family: var(--t-mono); font-size: .68rem; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; padding: 3px 9px;
  border-radius: 999px; white-space: nowrap;
  color: var(--t-leaf-deep); background: rgba(0, 200, 120, .13); }
.t-status.illustrative { color: #8A5F00; background: rgba(255, 194, 75, .2); }
.t-status.estimate { color: #B92F20; background: rgba(255, 106, 90, .16); }
.t-dark .t-status { color: var(--t-leaf-bright); background: rgba(15, 226, 140, .14); }
.t-dark .t-status.illustrative { color: var(--t-pollen); background: rgba(255, 194, 75, .16); }
.t-dark .t-status.estimate { color: #FF8B7E; background: rgba(255, 106, 90, .16); }

/* ---------------------------------------------------------- numbers */
.t-figure { font-family: var(--ob-font-display); font-weight: 800;
  font-variant-numeric: tabular-nums; letter-spacing: -.02em; line-height: 1;
  font-size: clamp(2.1rem, 1.3rem + 2.6vw, 3.6rem); color: var(--t-ink); }
.t-figure .unit { font-size: .42em; color: var(--t-ink-2); margin-left: .2em;
  letter-spacing: 0; }
.t-figure em { font-style: normal; color: var(--t-leaf-deep); }
.t-dark .t-figure em { color: var(--t-leaf-bright); }
.t-figure-label { font-size: .92rem; color: var(--t-ink-2); margin-top: 10px;
  line-height: 1.4; max-width: 26ch; }

.t-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: clamp(20px, 3vw, 40px); }

/* ------------------------------------------------------------ cards */
/* Border, fill and shadow are spent by role, not stamped on every
   block. A plain card has a hairline and nothing else; only the one
   card that is the point of its section is lifted. */
.t-card { background: var(--t-paper); border: 1px solid var(--t-line);
  border-radius: 18px; padding: clamp(20px, 2.2vw, 30px);
  display: flex; flex-direction: column; gap: 12px; }
.t-card.t-lift { box-shadow: 0 1px 2px rgba(10, 46, 40, .05),
  0 30px 60px -34px rgba(10, 46, 40, .45); }
.t-card .t-card-top { display: flex; align-items: center; gap: 10px;
  justify-content: space-between; }
.t-card p { margin: 0; color: var(--t-ink-2); line-height: 1.52; font-size: .98rem; }
.t-grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: clamp(14px, 1.6vw, 22px); }
.t-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(14px, 1.6vw, 22px); }
.t-grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(12px, 1.4vw, 20px); }

/* the asymmetric editorial split that replaces centred hero + 3 cards */
.t-split { display: grid; grid-template-columns: minmax(0, 1.02fr) minmax(0, .98fr);
  gap: clamp(28px, 4vw, 72px); align-items: center; }
.t-split.t-split-wide { grid-template-columns: minmax(0, 1.25fr) minmax(0, .75fr); }
.t-split.t-top { align-items: start; }

/* ---------------------------------------------------------- buttons */
.ob-btn { border-radius: 999px; font-weight: 700; letter-spacing: -.005em;
  transition: transform .18s var(--t-ease), box-shadow .18s var(--t-ease),
              background-color .18s, border-color .18s, color .18s; }
.ob-btn-primary { background: var(--t-leaf); border-color: var(--t-leaf);
  color: #04241C; box-shadow: 0 10px 26px -14px rgba(0, 200, 120, .9); }
.ob-btn-primary:hover { background: var(--t-leaf-bright); border-color: var(--t-leaf-bright);
  transform: translateY(-1px); box-shadow: 0 16px 34px -16px rgba(0, 200, 120, .95); }
.t-dark .ob-btn-ghost, .t-dark .ob-btn-secondary {
  color: var(--t-on-deep); border-color: var(--t-line-deep); background: transparent; }
.t-dark .ob-btn-ghost:hover, .t-dark .ob-btn-secondary:hover {
  border-color: var(--t-leaf-bright); color: var(--t-leaf-bright); }

.t-actions { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; }
.t-actions .t-aside { font-size: .86rem; color: var(--t-ink-3); }

/* ------------------------------------------------------- the probe */
/* The live rate probe: pick a market and a material, see the rate with
   its citation, its date and its status. It is the entire proposition
   in one interaction, and it is the one thing on this site a competitor
   cannot put on theirs. */
.probe { background: rgba(255, 255, 255, .05); border: 1px solid var(--t-line-deep);
  border-radius: 22px; padding: clamp(18px, 2vw, 26px);
  box-shadow: 0 40px 90px -50px rgba(0, 0, 0, .9); }
.probe-head { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 14px; }
.probe-head .t-eyebrow { margin: 0; }
.probe-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.probe-fields label { display: block; font-family: var(--t-mono); font-size: .68rem;
  letter-spacing: .14em; text-transform: uppercase; color: var(--t-on-deep-3);
  margin-bottom: 6px; }
.probe-fields select { width: 100%; font: inherit; font-size: .96rem; font-weight: 600;
  color: var(--t-on-deep); background: rgba(4, 18, 15, .55);
  border: 1px solid var(--t-line-deep); border-radius: 12px; padding: 11px 12px;
  appearance: none; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%239FC4B6' stroke-width='1.8' stroke-linecap='round'%3E%3Cpath d='M3 4.5 6 7.5 9 4.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center; }
.probe-fields select:focus-visible { outline: 3px solid var(--t-bridge); outline-offset: 2px; }
.probe-out { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--t-line-deep);
  display: grid; gap: 10px; }
.probe-rate { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.probe-rate .t-figure { color: var(--t-on-deep); font-size: clamp(2rem, 1.3rem + 2.2vw, 3.1rem); }
.probe-rate .t-figure .unit { color: var(--t-on-deep-2); }
.probe-what { font-size: .95rem; color: var(--t-on-deep-2); line-height: 1.5; margin: 0; }
.probe-out.is-swapping { opacity: .25; }
.probe-out { transition: opacity .18s ease; }
.probe-foot { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-top: 14px; padding-top: 13px;
  border-top: 1px solid var(--t-line-deep); }
.probe-foot .t-note { font-size: .78rem; color: var(--t-on-deep-3); margin: 0; }

/* ------------------------------------------------------- regime rail */
/* Eleven regimes is the fact that most changes how big the product
   looks, and it was buried in a card grid. Here it is a single rail.

   NAMED t-rail, NOT rail. `.rail` already belongs to site.css, where it
   is the Packaging Builder's scrolling goal marquee: a masked,
   overflow-hidden wrapper around `.rail-track > span.rail-group`. This
   file loads after site.css, so `.rail span` was reaching every span
   inside that marquee - the group wrapper included - and dressing them
   as mono chips with borders and `white-space: nowrap`. Two components
   cannot share a class name across two stylesheets that both load. */
.t-rail { display: flex; flex-wrap: wrap; gap: 8px; }
.t-rail > span { font-family: var(--t-mono); font-size: .78rem; font-weight: 500;
  padding: 7px 13px; border-radius: 999px; border: 1px solid var(--t-line);
  color: var(--t-ink-2); background: var(--t-paper); white-space: nowrap; }
.t-dark .t-rail > span { background: rgba(255, 255, 255, .04); }
.t-rail > span.on { border-color: var(--t-leaf); color: var(--t-leaf-deep);
  background: rgba(0, 200, 120, .1); font-weight: 700; }
.t-dark .t-rail > span.on { color: var(--t-leaf-bright); background: rgba(15, 226, 140, .12); }

/* ------------------------------------------------ the absence panel */
/* A proven no and an empty cell look identical everywhere else in this
   market, and they are not the same thing. This gets its own treatment
   because it is the least copyable claim on the site. */
.absence { border: 1px solid var(--t-line); border-left: 3px solid var(--t-leaf);
  border-radius: 0 16px 16px 0; padding: 20px 24px; background: var(--t-paper);
  display: grid; gap: 10px; }
.absence q { font-style: normal; font-size: 1.06rem; line-height: 1.5;
  color: var(--t-ink); quotes: none; }

/* -------------------------------------------------------- step list */
/* SCOPED TO ol.steps ON PURPOSE. `.steps` is also a component in
   oblifee.css - a row of cards, `div.steps > div.step`, used on the
   Consultants, Packaging Builder and Drinks pages. Both stylesheets
   load, and the cascade merges them property by property rather than
   letting one win whole: this file's `gap: 2px` was reaching that card
   row, and oblifee.css's
   `grid-template-columns: repeat(auto-fit, minmax(215px, 1fr))` was
   reaching this numbered list, which is why four full-width steps
   rendered as four 259px columns. The theme's list is always an <ol>
   and the kit's row is always a <div>, so the element selector
   separates them for good, and the properties each stylesheet was
   leaking are restated here rather than left to load order. */
.ob-root ol.steps { counter-reset: step; display: grid; gap: 2px;
  grid-template-columns: 1fr; margin-top: 0; padding: 0; }
.ob-root ol.steps > li { list-style: none; display: grid;
  grid-template-columns: 52px minmax(0, 1fr);
  column-gap: 18px; row-gap: 0; align-items: start; padding: 20px 0;
  border-top: 1px solid var(--t-line); }
.ob-root ol.steps > li:last-child { border-bottom: 1px solid var(--t-line); }
.ob-root ol.steps > li::before { counter-increment: step;
  content: counter(step, decimal-leading-zero);
  grid-column: 1; grid-row: 1;
  font-family: var(--t-mono); font-size: .82rem; font-weight: 600;
  color: var(--t-leaf-deep); padding-top: 3px; letter-spacing: .06em; }
.t-dark ol.steps > li::before { color: var(--t-leaf-bright); }
/* Both of these are placed in column two by name. A row of this list
   has THREE children - the ::before counter, the <b> and the <p> - in a
   TWO column grid, so auto-placement put the counter at 1/1, the <b> at
   1/2, and wrapped the <p> onto 2/1, which is the 52px counter column:
   the paragraph rendered 52px wide, one word per line. Naming the
   column is the fix; widening the track only hides it. */
.ob-root ol.steps > li b { grid-column: 2; display: block;
  font-family: var(--ob-font-display); font-weight: 800;
  font-size: 1.08rem; margin-bottom: 5px; }
.ob-root ol.steps > li p { grid-column: 2; margin: 0; color: var(--t-ink-2);
  font-size: .97rem; line-height: 1.5; }

/* --------------------------------------------------------- compare */
.t-table-wrap { overflow-x: auto; border: 1px solid var(--t-line);
  border-radius: 16px; background: var(--t-paper); }
.t-table { width: 100%; border-collapse: collapse; font-size: .95rem;
  font-variant-numeric: tabular-nums; }
.t-table th { text-align: left; font-family: var(--t-mono); font-weight: 600;
  font-size: .7rem; letter-spacing: .13em; text-transform: uppercase;
  color: var(--t-ink-3); padding: 14px 18px; border-bottom: 1px solid var(--t-line);
  white-space: nowrap; }
.t-table td { padding: 14px 18px; border-bottom: 1px solid var(--t-line);
  color: var(--t-ink-2); vertical-align: top; }
.t-table tr:last-child td { border-bottom: 0; }
.t-table td:first-child { color: var(--t-ink); font-weight: 700; }
.t-table td.yes { color: var(--t-leaf-deep); font-weight: 700; }
.t-table td.no { color: var(--t-ink-3); }

/* ----------------------------------------------------- request form */
.t-form { display: grid; gap: 16px; max-width: 560px; }
.t-field { display: grid; gap: 7px; }
.t-field label { font-family: var(--t-mono); font-size: .7rem; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--t-ink-3); }
.t-field input, .t-field textarea, .t-field select {
  font: inherit; font-size: 1rem; color: var(--t-ink); background: var(--t-paper);
  border: 1.5px solid var(--t-line); border-radius: 12px; padding: 13px 15px;
  width: 100%; box-sizing: border-box; }
.t-field textarea { min-height: 110px; resize: vertical; line-height: 1.5; }
.t-field input:focus-visible, .t-field textarea:focus-visible,
.t-field select:focus-visible { outline: 3px solid var(--t-leaf-deep); outline-offset: 1px;
  border-color: transparent; }
.t-field .hint { font-size: .82rem; color: var(--t-ink-3); }
.t-field.t-invalid input, .t-field.t-invalid textarea { border-color: var(--t-coral); }
.t-field .err { font-size: .82rem; color: #B92F20; }
/* the honeypot: a real field, positioned out of sight, never focusable */
.t-trap { position: absolute; left: -9999px; width: 1px; height: 1px;
  overflow: hidden; }
.t-formnote { font-size: .88rem; color: var(--t-ink-2); line-height: 1.55;
  max-width: 52ch; }
.t-result { border-radius: 16px; padding: 22px 24px; display: grid; gap: 8px;
  border: 1px solid var(--t-leaf); background: rgba(0, 200, 120, .08); }
/* An author `display` beats the user agent's `[hidden] { display: none }`,
   so `<div class="t-result" hidden>` drew its own empty bordered box on
   every load of the request page, before there was anything to say in
   it. The box arrives with the message now, not before it. */
.t-result[hidden] { display: none; }
.t-result.bad { border-color: var(--t-coral); background: rgba(255, 106, 90, .08); }
.t-result b { font-family: var(--ob-font-display); font-size: 1.2rem; }

/* ---------------------------------------------------------- footer */
.site-footer { background: var(--t-kelp); color: var(--t-on-deep-2);
  border-top: 0; margin-top: 0; padding: clamp(48px, 6vw, 76px) 0 40px; }
.site-footer a, .site-footer .ob-link { color: var(--t-on-deep-2); }
.site-footer a:hover, .site-footer .ob-link:hover { color: var(--t-leaf-bright); }
.site-footer .ls-line .ls-icon { color: #8FB3A6; }
.site-footer .ls-madeby { color: var(--t-on-deep-3); }
.site-footer .ls-word.light { display: none; }
.site-footer .ls-word.dark { display: block; }
.t-foot-grid { display: grid; grid-template-columns: 1.4fr repeat(3, 1fr);
  gap: clamp(24px, 3vw, 48px); padding-bottom: 40px;
  border-bottom: 1px solid var(--t-line-deep); margin-bottom: 26px; }
.t-foot-grid h4 { font-family: var(--t-mono); font-size: .7rem; font-weight: 600;
  letter-spacing: .15em; text-transform: uppercase; color: var(--t-on-deep-3);
  margin: 0 0 14px; }
.t-foot-grid ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.t-foot-grid a { text-decoration: none; font-size: .95rem; }
.t-foot-lead { font-size: .98rem; line-height: 1.55; max-width: 34ch; margin: 14px 0 0;
  color: var(--t-on-deep-3); }

/* -------------------------------------------------------- motion */
/* One idea, used sparingly: things arrive from below as they are
   reached, and nothing moves once it has arrived. The page at rest is
   the page as read. */
.t-rise { opacity: 0; transform: translateY(20px);
  transition: opacity .6s var(--t-ease), transform .6s var(--t-ease); }
.t-rise.in { opacity: 1; transform: none; }
.t-rise-2 { transition-delay: .08s; }
.t-rise-3 { transition-delay: .16s; }
.t-rise-4 { transition-delay: .24s; }

@media (prefers-reduced-motion: reduce) {
  .t-rise { opacity: 1; transform: none; transition: none; }
  .ob-btn:hover { transform: none; }
}

/* ---------------------------------------------------------- mobile */
@media (max-width: 980px) {
  .t-split, .t-split.t-split-wide { grid-template-columns: 1fr; }
  .t-grid-3, .t-grid-4 { grid-template-columns: repeat(2, 1fr); }
  .t-foot-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 620px) {
  .t-grid-2, .t-grid-3, .t-grid-4 { grid-template-columns: 1fr; }
  .t-foot-grid { grid-template-columns: 1fr; }
  .probe-fields { grid-template-columns: 1fr; }
  .ob-root ol.steps > li { grid-template-columns: 34px minmax(0, 1fr); column-gap: 12px; }
}

/* =====================================================================
   ONE PAGE, TWELVE TIMES

   WHY THIS BLOCK EXISTS. The theme above was written as a set of
   classes and then applied in full to two pages. The other ten kept the
   older marketing kit underneath it and bolted on only the spine, so
   the same headline rendered at 44px, 46px, 48px and 53px on four
   pages, section headings ran from 21px to 51px, four heroes were
   centred and four were not, and the band rhythm came from
   `.feat { padding: 66px }` on some pages and `clamp(72px, 9vw, 132px)`
   on others.

   Almost none of that was a missing rule. It was SPECIFICITY. oblifee.css
   sets `.ob-root h1, .ob-root h2, .ob-root h3 { line-height: 1.15 }` at
   (0,1,1), and every type rule in this file is one class at (0,1,0), so
   no display leading in this theme ever reached a heading; the same
   goes for per-page `.hero h1 { font-size: … }` blocks against
   `.t-display`. Scoping the theme's own classes under `.ob-root` puts
   them at (0,2,0) and back in charge, which is why this block is mostly
   the selectors above written once more with a prefix.

   Nothing here needs a page's markup to change. A page that already
   carries `t-display`, `t-pa` and `t-h2` lands on the home page's
   ladder by loading this file.
   ===================================================================== */

/* ------------------------------------------------- the type ladder */
/* Leading falls as size rises, which is the ladder the flat 1.15 was
   standing in for. Bricolage's ascent-plus-descent box is about 1.2em,
   so display sizes are set just under it deliberately - a headline is
   read as a shape - while anything at reading size is given room. */
.ob-root h1, .ob-root h2, .ob-root h3, .ob-root .ob-h3 { line-height: 1.3; }

.ob-root .t-display { line-height: 1.1; letter-spacing: -.028em; }
.ob-root .t-h2 { line-height: 1.12; letter-spacing: -.022em; }
.ob-root .t-h3 { line-height: 1.25; }

/* One hero headline size for the whole site. Every page's hero h1
   already carries `t-display t-problem`; the home page adds `t-hero`
   for the step down from full display size, and this makes that step
   the rule rather than the exception. `.ob-root h1.t-display` is
   (0,2,1), which is what it takes to beat `.hero h1` and `.maphead h1`
   in the per-page <style> blocks. */
.ob-root h1.t-display, .ob-root .t-display.t-hero {
  font-size: clamp(2.05rem, 1.25rem + 2.1vw, 3.32rem);
  line-height: 1.08;
  max-width: 19ch;
}
/* Section headings on the pages that never got `t-h2`: the kit's
   `.feat h2` clamp(26px, 3.4vw, 34px) put them a third smaller than the
   home page's. Same ladder now, and `max-width` so a long one breaks
   like the home page's rather than running the full container. */
.ob-root .feat h2,
.ob-root section > .ob-container > h2 {
  font-size: clamp(1.9rem, 1.2rem + 2.2vw, 3.1rem);
  line-height: 1.12; letter-spacing: -.022em;
  text-wrap: balance; max-width: 22ch;
}

/* ------------------------------------------------------- one hero */
/* The kit's `.hero` and the theme's `.t-band` were two different
   rhythms, and the two theme pages then overrode the band inline, so
   three heroes had three different openings. `t-hero-band` is the band
   version of the same measurement: the distance from the header to the
   first headline is now one number for the whole site. */
.ob-root .hero,
.ob-root .t-band.t-hero-band {
  padding: clamp(52px, 6.4vw, 96px) 0 clamp(40px, 4.6vw, 68px);
  text-align: left;
}
/* Four pages centred their hero in a per-page <style> block. See the
   note on the spine below for why every hero is left aligned now. */
.ob-root .hero .lead, .ob-root .hero p.lead, .ob-root .hero .t-note,
.ob-root .hero .ob-body {
  margin-left: 0; margin-right: 0; text-align: left;
}
.ob-root .hero .actions, .ob-root .t-actions {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 12px; justify-content: flex-start;
}
.ob-root .hero .actions { margin-top: 28px; }

/* --------------------------------------------------- the spine */
/* THE ONE TREATMENT, AND WHY.  `.t-answer` is a two column grid whose
   first column is a 3px gradient rule standing against the left edge of
   a 60ch measure. That rule is a landmark: it says "the answer starts
   here". Centre the text and the rule is stranded beside a ragged
   block, pointing at nothing, which is exactly what Pricing, Modules,
   Drinks and Security were showing. The alternatives were to drop the
   rule when the hero is centred - the spine then looks like two
   different components on one site - or to centre the whole spine as a
   block with the rule still on its left, which moves the problem rather
   than solving it. The home page is the reference and it is left
   aligned, and a 60ch measure with a rule at its head reads fastest
   ragged right. So: left, everywhere, rule always at the answer's left
   edge. */
.ob-root .t-pa { display: grid; gap: clamp(18px, 1.7vw, 24px);
  text-align: left; justify-items: start; max-width: 46rem; }
.ob-root .t-pa .t-answer { text-align: left; justify-self: start; }
.ob-root .t-pa > .t-problem { max-width: 19ch; }
/* the supporting note always sits under the spine, at the same distance */
.ob-root .hero .t-pa + .t-note, .ob-root .hero .t-pa + p { margin-top: 22px; }

/* --------------------------------------------- the section rhythm */
/* `.feat` was a flat 66px on eight pages while the home page breathed
   on the band scale. Matched to `.t-band + .t-band`, which is the
   spacing between two consecutive bands - which is what consecutive
   `.feat` sections are. */
.ob-root section.feat, .ob-root .feat { padding: clamp(56px, 7vw, 104px) 0; }
.ob-root .feat.flush { padding-top: clamp(28px, 3.5vw, 52px); }
.ob-root .cards3, .ob-root .cards2 { margin-top: clamp(24px, 2.6vw, 38px); }

/* --------------------------------------------------------- mobile */
@media (max-width: 700px) {
  .ob-root h1.t-display, .ob-root .t-display.t-hero { max-width: none; }
  .ob-root .t-pa > .t-problem { max-width: none; }
}

/* =====================================================================
   BUILD YOUR QUOTE
   The questionnaire panel (Pricing) and the quote itself (Quote). Both
   are built from the same components as the rest of the theme, because a
   quote is a set of figures and figures on this site carry their
   workings.
   ===================================================================== */

/* ------------------------------------------------ the panel shell */
.qpanel[hidden] { display: none !important; }
.qpanel { position: fixed; inset: 0; z-index: 80; display: grid;
  place-items: end center; padding: 0; }
.qpanel::before { content: ''; position: absolute; inset: 0;
  background: rgba(4, 18, 15, .55); backdrop-filter: blur(3px); }
.qpanel-box { position: relative; width: min(780px, 100%);
  max-height: min(92vh, 980px); overflow: auto; overscroll-behavior: contain;
  background: var(--t-paper); color: var(--t-ink);
  border: 1px solid var(--t-line); border-radius: 22px 22px 0 0;
  padding: clamp(22px, 3vw, 36px); box-shadow: 0 -30px 90px -40px rgba(4, 18, 15, .8); }
@media (min-width: 760px) {
  .qpanel { place-items: center; padding: 24px; }
  .qpanel-box { border-radius: 22px; }
}
.qpanel-head { display: flex; align-items: start; justify-content: space-between;
  gap: 16px; margin-bottom: 6px; }
.qclose { flex: none; background: none; border: 1px solid var(--t-line);
  border-radius: 999px; width: 34px; height: 34px; cursor: pointer;
  color: var(--t-ink-2); font-size: 17px; line-height: 1; }
.qclose:hover { border-color: var(--t-coral); color: var(--t-coral); }
body.qpanel-open { overflow: hidden; }

/* ------------------------------------------------ the stepped question */
/* One idea per screen, set at a size that reads as answerable rather
   than shouted, on the theme's own parts: the mono face wherever
   something reads as measurement, the spine's spacing rhythm, and no
   colour doing decorative work. */
.qstage { min-height: 300px; }
.qstep { display: grid; gap: 0; animation: qin .22s var(--t-ease) both; }
@media (prefers-reduced-motion: reduce) { .qstep { animation: none; } }
@keyframes qin { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.qstep .qnum { font-family: var(--t-mono); font-size: .72rem; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase; color: var(--t-leaf-deep);
  margin-bottom: 12px; }
.qstep .qq { font-family: var(--ob-font-display); font-weight: 800;
  font-size: clamp(1.24rem, 1.06rem + .8vw, 1.72rem); line-height: 1.2;
  letter-spacing: -.018em; color: var(--t-ink); margin: 0; max-width: 24ch; }
.qstep .qq:focus { outline: none; }
.qstep .qq:focus-visible { outline: 3px solid var(--t-leaf-deep); outline-offset: 4px;
  border-radius: 4px; }
.qhelp { margin: 12px 0 0; font-size: .93rem; line-height: 1.55;
  color: var(--t-ink-2); max-width: 56ch; }
.qopts { display: flex; flex-wrap: wrap; gap: 9px; margin: 24px 0 0; }
.qopts.qmany { flex-direction: column; align-items: stretch; max-width: 34rem; }
.qopt { display: inline-flex; align-items: center; gap: 10px; cursor: pointer;
  border: 1.5px solid var(--t-line); border-radius: 999px; padding: 11px 18px;
  font-size: .96rem; font-weight: 600; color: var(--t-ink-2);
  background: var(--t-paper); position: relative;
  transition: border-color .15s, color .15s, background-color .15s; }
.qopts.qmany .qopt { border-radius: 14px; justify-content: flex-start; }
.qopt input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.qopt:hover { border-color: var(--t-leaf); color: var(--t-ink); }
.qopt.on { border-color: var(--t-leaf); background: rgba(0, 200, 120, .1);
  color: var(--t-leaf-deep); }
.qopts.qmany .qopt::before { content: ''; width: 17px; height: 17px; flex: none;
  border: 1.5px solid var(--t-line); border-radius: 5px; }
.qopts.qmany .qopt.on::before { border-color: var(--t-leaf); background: var(--t-leaf);
  box-shadow: inset 0 0 0 3px var(--t-paper); }
.qopt:focus-within { outline: 3px solid var(--t-leaf-deep); outline-offset: 2px; }
.qerr { margin: 16px 0 0; font-size: .86rem; color: #B92F20; font-weight: 600; }
.qerr[hidden] { display: none; }

/* Progress that does not promise a total it might not keep. The
   segments are the path as the current answers make it, and the line
   underneath says so rather than printing "step 3 of 9". */
.qprog { display: grid; gap: 9px; margin: 20px 0 26px; }
.qprog-bar { display: flex; gap: 4px; }
.qprog-bar i { height: 3px; flex: 1 1 0; border-radius: 2px;
  background: var(--t-line); transition: background-color .2s; }
.qprog-bar i.done { background: var(--t-leaf); }
.qprog-bar i.now { background: var(--t-ink); }
.qprog-say { font-family: var(--t-mono); font-size: .7rem; letter-spacing: .08em;
  color: var(--t-ink-3); }

/* What an answer took off the path. Bridge teal, because it is
   information about the form rather than a status on a fact, and the
   three status colours must not be spent on anything but status. */
.qnotice { margin: 0 0 18px; padding: 12px 15px; border-radius: 12px;
  border-left: 3px solid var(--t-bridge); background: rgba(47, 200, 194, .09);
  font-size: .9rem; line-height: 1.5; color: var(--t-ink-2); }
.qnotice[hidden] { display: none; }

/* The review. Plain words, each one editable, because this is also what
   makes the quote defensible when somebody opens it later. */
.qreview { display: grid; gap: 2px; margin-top: 22px; }
.qrow { display: grid; grid-template-columns: minmax(0, 11rem) minmax(0, 1fr) auto;
  gap: 14px; align-items: baseline; padding: 13px 0;
  border-top: 1px solid var(--t-line); }
.qrow:last-child { border-bottom: 1px solid var(--t-line); }
.qrow-k { grid-column: 1; font-family: var(--t-mono); font-size: .7rem;
  font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: var(--t-ink-3); }
.qrow-v { grid-column: 2; font-size: .96rem; line-height: 1.45; color: var(--t-ink);
  font-weight: 600; }
.qrow-edit { grid-column: 3; background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; font-size: .85rem; font-weight: 700; color: var(--t-leaf-deep);
  text-decoration: underline; text-underline-offset: 3px; }
.qrow-edit:hover { color: var(--t-ink); }
.qrow-edit:focus-visible { outline: 3px solid var(--t-leaf-deep); outline-offset: 3px; }

.qactions { display: flex; flex-wrap: wrap; gap: 12px; align-items: center;
  margin-top: 28px; padding-top: 20px; border-top: 1px solid var(--t-line); }
.qactions [data-quote-back][hidden] { display: none; }

@media (max-width: 620px) {
  .qrow { grid-template-columns: minmax(0, 1fr) auto; }
  .qrow-k { grid-column: 1 / -1; }
  .qrow-v { grid-column: 1; }
  .qrow-edit { grid-column: 2; }
}

/* --------------------------------------------------- the quote */
.qsum { display: grid; gap: 14px; }
.qline { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 10px 18px;
  align-items: baseline; padding: 18px 0; border-top: 1px solid var(--t-line); }
.qline:first-child { border-top: 0; padding-top: 0; }
/* Three children in a two column grid is how the step list broke, so
   every part of this row names its column. */
.qline .qname { grid-column: 1; font-family: var(--ob-font-display);
  font-weight: 800; font-size: 1.06rem; color: var(--t-ink); }
.qline .qprice { grid-column: 2; grid-row: 1; font-family: var(--ob-font-display);
  font-weight: 800; font-variant-numeric: tabular-nums; white-space: nowrap;
  font-size: 1.12rem; color: var(--t-ink); }
.qline .qprice small { font-family: var(--ob-font-body); font-size: .78rem;
  font-weight: 600; color: var(--t-ink-3); margin-left: 4px; }
.qline .qwhy { grid-column: 1 / -1; margin: 0; font-size: .94rem; line-height: 1.55;
  color: var(--t-ink-2); max-width: 68ch; }
.qtotals { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: clamp(16px, 2.4vw, 32px); margin-top: 4px; padding-top: 24px;
  border-top: 2px solid var(--t-ink); }
.qtotal .t-figure { font-size: clamp(1.9rem, 1.2rem + 2vw, 3rem); }
.qtotal p { margin: 8px 0 0; font-size: .9rem; color: var(--t-ink-2); line-height: 1.45; }
.qnotes { display: grid; gap: 10px; margin-top: 22px; }
.qnote { display: grid; grid-template-columns: auto 1fr; gap: 12px;
  font-size: .94rem; line-height: 1.55; color: var(--t-ink-2); }
.qnote::before { content: ''; width: 3px; border-radius: 2px; align-self: stretch;
  background: var(--t-bridge); }
.qanswers { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.qanswers button { font-family: var(--t-mono); font-size: .72rem; padding: 6px 12px;
  border-radius: 999px; border: 1px solid var(--t-line); color: var(--t-ink-2);
  background: var(--t-paper); cursor: pointer; line-height: 1.4; }
.qanswers button b { color: var(--t-ink-3); font-weight: 600; }
.qanswers button:hover { border-color: var(--t-leaf); color: var(--t-ink); }
.qanswers button:focus-visible { outline: 3px solid var(--t-leaf-deep); outline-offset: 2px; }
.qempty { display: grid; gap: 18px; max-width: 60ch; }

/* =====================================================================
   THE SURFACES SLIDER (Obli)

   Five doors onto one assistant. The point being made is that the
   answer is the same through every one of them, so the panels are
   deliberately near-identical: the same question, the same figure, the
   same receipt. What changes between them is the line at the bottom
   saying what that door adds and what it cannot do.

   Built in this site's own language rather than with other companies'
   logos and interface chrome: we hold no licence for those, and a
   screenshot of somebody else's product is out of date the week they
   reskin it. Each surface is named in type instead.
   ===================================================================== */
.surf { display: grid; gap: clamp(18px, 2vw, 26px); }
.surf-tabs { display: flex; flex-wrap: wrap; gap: 8px; }
.surf-tab { font-family: var(--t-mono); font-size: .76rem; font-weight: 600;
  letter-spacing: .04em; padding: 9px 15px; border-radius: 999px;
  border: 1.5px solid var(--t-line); background: var(--t-paper);
  color: var(--t-ink-2); cursor: pointer; white-space: nowrap;
  transition: border-color .16s, color .16s, background-color .16s; }
.surf-tab:hover { border-color: var(--t-leaf); color: var(--t-ink); }
.surf-tab[aria-selected="true"] { border-color: var(--t-leaf);
  background: rgba(0, 200, 120, .1); color: var(--t-leaf-deep); }
.surf-tab:focus-visible { outline: 3px solid var(--t-leaf-deep); outline-offset: 2px; }

.surf-stage { position: relative; }
.surf-panel[hidden] { display: none; }
/* The frame. A window with a title bar, drawn in the theme's own parts,
   named by the surface rather than by a borrowed logo. */
.surf-panel { border: 1px solid var(--t-line); border-radius: 18px;
  background: var(--t-paper); overflow: hidden;
  box-shadow: 0 1px 2px rgba(10, 46, 40, .05), 0 30px 60px -38px rgba(10, 46, 40, .45); }
.surf-bar { display: flex; align-items: center; gap: 10px;
  padding: 12px 18px; border-bottom: 1px solid var(--t-line);
  background: var(--t-mist); }
.surf-bar .dots { display: inline-flex; gap: 5px; }
.surf-bar .dots i { width: 8px; height: 8px; border-radius: 50%;
  background: var(--t-line); display: block; }
.surf-bar b { font-family: var(--t-mono); font-size: .72rem; font-weight: 600;
  letter-spacing: .13em; text-transform: uppercase; color: var(--t-ink-2); }
.surf-bar .where { margin-left: auto; font-size: .78rem; color: var(--t-ink-3); }
.surf-body { padding: clamp(18px, 2.2vw, 28px); display: grid; gap: 14px; }
.surf-ask { justify-self: end; max-width: 32ch; background: var(--t-kelp);
  color: var(--t-on-deep); border-radius: 16px 16px 4px 16px;
  padding: 11px 15px; font-size: .95rem; line-height: 1.45; }
.surf-say { max-width: 54ch; background: var(--t-mist); border-radius: 16px 16px 16px 4px;
  padding: 14px 16px; display: grid; gap: 10px; }
.surf-say p { margin: 0; font-size: .96rem; line-height: 1.55; color: var(--t-ink); }
.surf-fig { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.surf-fig .t-figure { font-size: clamp(1.5rem, 1.1rem + 1.2vw, 2.1rem); }
.surf-foot { border-top: 1px solid var(--t-line); padding: 14px clamp(18px, 2.2vw, 28px);
  display: grid; gap: 6px; background: var(--t-mist); }
.surf-foot b { font-size: .84rem; color: var(--t-ink); }
.surf-foot span { font-size: .88rem; line-height: 1.5; color: var(--t-ink-2); }
.surf-foot .cannot { color: var(--t-ink-3); }
@media (max-width: 620px) {
  .surf-ask { justify-self: stretch; max-width: none; }
}

/* ------------------------------------- the one centred spine (Pricing) */
/* A DELIBERATE ONE-OFF, not a second treatment. Every other hero on the
   site is left aligned, because `.t-answer`'s gradient rule is a
   landmark that says where the answer starts, and a rule beside centred
   text points at a ragged edge and marks nothing. The Pricing hero is
   centred by an explicit instruction, so rather than centre the text and
   leave the rule stranded, this variant DROPS the rule and centres the
   whole block: a centred answer is a different shape, and it should
   either be one thing or the other.

   If the Pricing hero is ever left aligned again, delete this block
   rather than adding a competing alignment: `.t-pa-centred` should have
   exactly one user. */
.ob-root .t-pa.t-pa-centred { justify-items: center; text-align: center;
  margin-left: auto; margin-right: auto; }
.ob-root .t-pa.t-pa-centred > .t-problem { max-width: 24ch; }
.ob-root .t-pa.t-pa-centred .t-answer { grid-template-columns: minmax(0, 1fr);
  text-align: center; justify-self: center; }
.ob-root .t-pa.t-pa-centred .t-answer::before { content: none; }
.ob-root .hero:has(> .ob-container > .t-pa-centred) { text-align: center; }
.ob-root .hero:has(> .ob-container > .t-pa-centred) .t-eyebrow,
.ob-root .hero:has(> .ob-container > .t-pa-centred) .actions,
.ob-root .hero:has(> .ob-container > .t-pa-centred) .receipt {
  justify-content: center; text-align: center; }
.ob-root .hero:has(> .ob-container > .t-pa-centred) .receipt { display: flex; }
