/*
 * The account page's own few rules, on castomo-dashkit's tokens.
 *
 * Everything else is the kit's (dashkit.css and castomo's theme). Nothing here
 * types a colour, a font size or letter-spacing: colours and type steps are the
 * kit's variables, so light, dark and high contrast are the kit's work too, and
 * layout uses logical properties so a right-to-left language mirrors by itself.
 */

/* Rhythm (kit GUIDELINES §4): one rule spaces a screen's blocks; no block carries its own margin. */
#view > * + * { margin-block-start: var(--gap); }
.page-tabs > .tabs { margin-block-end: var(--gap); }

.muted { color: var(--ink-3); font-size: var(--t-1); }

/* Three tiles in a row share their inner rows, so badges, sentences and buttons line up (§5e). */
.status-tiles > .card {
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 4;
  gap: var(--s1);
}
.status-tiles > .card > .card-head { margin-block-end: 0; }
.status-tiles > .card > .card-foot { align-self: end; }
@media (max-width: 860px) {
  .status-tiles { grid-template-columns: minmax(0, 1fr); }
}

.card-title > .ci { margin-inline-end: var(--s0); }

/* An address is a single long word: it breaks anywhere rather than pushing the tile wider. */
.fact-value { color: var(--ink); font-weight: 650; overflow-wrap: anywhere; }
.list-main small { overflow-wrap: anywhere; }

/* Badges beside a list row wrap under each other on a phone instead of squeezing the row. */
.list .badges { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--s0); }
@media (max-width: 480px) {
  .list > li { flex-wrap: wrap; }
  .list .badges { justify-content: flex-start; inline-size: 100%; padding-inline-start: 44px; }
  .list > li > .btn { margin-inline-start: 44px; }
}

/* Forms read best at a measure, not the full width of a wide card. */
.form-narrow { max-inline-size: 30rem; }

/* The password field's show/hide button sits inside the field, at its end. */
.input-wrap.pw-wrap > .input { padding-inline-start: 14px; padding-inline-end: 52px; }
.input-wrap.pw-wrap > .reveal { position: absolute; inset-inline-end: 2px; }

/* A one-time code is read digit by digit: monospace, the one other family the kit allows. */
.code-input { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; max-inline-size: 14rem; }

/* Enrolment's three steps, numbered by the list itself. */
.steps-plain { display: grid; list-style: decimal; gap: var(--s2); padding-inline-start: 1.4em; margin-block-end: var(--s2); }
.steps-plain > li { display: grid; gap: var(--s1); color: var(--ink-2); }

/* Recovery codes: two columns of monospace, never wider than the card. */
.codes { list-style: none; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s0) var(--s2); margin-block: var(--s2); }
.codes code { overflow-wrap: anywhere; }

/* A secret is code and stays left-to-right in any language. */
.secret code { direction: ltr; unicode-bidi: isolate; }
/* A QR code is always dark on white with its own quiet zone, whatever the theme: a themed one is a code cameras refuse. */
.qr { display: block; width: 14rem; max-width: 100%; height: auto; margin-block: var(--s2, 0.5rem); border-radius: 0.5rem; }

/* The signed-out card's headline: two authored lines at the kit's --t3 step. */
.auth-title { font-size: var(--t3); }

/* A card's own blocks (a badge, a sentence, a form, a row of buttons) never touch. */
#view .card { gap: var(--s1); }
#view .card > .card-head { margin-block-end: var(--s0); }

/* Products beside the castomAPI tile: the list takes two thirds, the tile one; one column on a phone. */
.products-row { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
.castomapi-tile .card-foot { margin-block-start: auto; }
@media (max-width: 860px) {
  .products-row, .castomapi-grid { grid-template-columns: minmax(0, 1fr); }
}

/* Today, this week, this month: three rows, each with its mark, its points and whether it paid. */
.visits { list-style: none; display: grid; gap: var(--s1); padding: 0; margin: 0; }
.visits > li { display: flex; align-items: center; gap: var(--s2); }
.visits > li > .list-main { flex: 1; min-inline-size: 0; display: grid; }
.visits .visit-icon { display: inline-grid; place-items: center; inline-size: 36px; block-size: 36px; border-radius: 50%; background: var(--field); color: var(--ink-2); }
.visits > li.is-done .visit-icon { background: var(--accent-soft); color: var(--accent-ink); }
.visits small { color: var(--ink-3); }

/* Level, points and streak side by side, stacking when the card is narrow. */
.points-facts, .wallet-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr)); gap: var(--s2); }

/* A sign-in's address: code, left to right in any language. */
.sign-in-ip { color: var(--ink-3); }
.sign-in-ip code, .list-main code { direction: ltr; unicode-bidi: isolate; overflow-wrap: anywhere; }

/* The one place a new key's value is drawn: monospace, selectable, breaking anywhere, the copy button beside it. */
.api-key-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s1); margin-block-start: var(--s1); }
.api-key-value { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; overflow-wrap: anywhere; user-select: all; padding: var(--s0) var(--s1); border-radius: var(--radius-sm); background: var(--field); }
.key-form { display: grid; gap: var(--s1); max-inline-size: 30rem; }
.list > li.is-off { opacity: .72; }

/* A step done on this same screen, named inside a sentence (ui.js linkButton): the kit's `.link` on a
   button, because nothing is navigated to. The button's own box goes, so it sits in the line like the
   words around it and wraps with them; `.link` keeps its underline, which is a background. */
.link-btn { display: inline; appearance: none; border: 0; border-radius: 0; margin: 0; padding: 0 0 2px; font: inherit; font-weight: 600; text-align: start; cursor: pointer; }

/* ---------- Workspaces ---------- */

/* The business's first colour as a small tile (set as --swatch through CSSOM); a building on the field when none is known. */
.ws-swatch { display: inline-grid; place-items: center; flex: none; inline-size: 32px; block-size: 32px; border-radius: var(--radius-sm); background: var(--swatch, var(--field)); color: var(--ink-3); box-shadow: inset 0 0 0 var(--rule-w) var(--rule); }
.ws-swatch .ci { --ci-size: 18px; }
.card-title .ws-swatch { margin-inline-end: var(--s1); vertical-align: middle; }
.card-title .ws-name { overflow-wrap: anywhere; }
.ws-title { display: inline-flex; align-items: center; gap: var(--s1); min-inline-size: 0; overflow-wrap: anywhere; }

/* The list's tiles share their inner rows, so badges, lines and buttons line up across a row (§5e). */
.ws-tiles > .card { display: grid; grid-template-rows: subgrid; grid-row: span 4; gap: var(--s1); }
.ws-tiles > .card > .card-head { margin-block-end: 0; }
.ws-tiles > .card > .card-foot { align-self: end; }
/* A shared row taller than its badges must not stretch them into lozenges. */
.ws-badges { display: flex; flex-wrap: wrap; align-items: flex-start; align-content: flex-start; gap: var(--s0); }
@media (max-width: 860px) {
  .ws-tiles, .ws-about-row { grid-template-columns: minmax(0, 1fr); }
}

/* The role picker in a team row keeps to the width of its words. */
.ws-role { inline-size: auto; min-inline-size: 9rem; }

/* An invitation's two buttons stay together, and wrap under the row on a phone. */
.ws-row-actions { flex: none; flex-wrap: nowrap; gap: var(--s0); }
@media (max-width: 480px) {
  .list > li > .ws-row-actions { margin-inline-start: 44px; flex-wrap: wrap; }
}

/* A danger zone's two doors, each a heading, a sentence and its button. */
.danger-zone > .stack-sm + .stack-sm { padding-block-start: var(--s2); border-block-start: var(--rule-w) solid var(--rule); }

/* Facts about the business: the logo beside its words, then colours as labelled swatches. */
.ws-facts-head { display: flex; align-items: flex-start; gap: var(--s2); }
.ws-logo { flex: none; inline-size: 72px; block-size: 72px; object-fit: contain; padding: var(--s0); border-radius: var(--radius-sm); background: var(--paper); box-shadow: inset 0 0 0 var(--rule-w) var(--rule); }
.ws-colors { list-style: none; display: flex; flex-wrap: wrap; gap: var(--s1) var(--s2); padding: 0; margin: 0; }
.ws-colors > li { display: flex; align-items: center; gap: var(--s0); }
.ws-colors > li > span:last-child { display: grid; line-height: 1.3; }
.ws-colors code { direction: ltr; unicode-bidi: isolate; }
.ws-colors small { color: var(--ink-3); font-size: var(--t-1); }
.ws-color { inline-size: 28px; block-size: 28px; border-radius: 50%; background: var(--swatch); box-shadow: inset 0 0 0 var(--rule-w) var(--rule); }
.ws-lines { display: grid; }
.ws-links { list-style: none; display: grid; gap: var(--s0); padding: 0; margin: 0; overflow-wrap: anywhere; }

/* Activity: the product chips wrap above the timeline; a product's name leads its line. */
.ws-chips { display: flex; flex-wrap: wrap; gap: var(--s0); }
.ws-timeline .tl-body p { overflow-wrap: anywhere; }

/* ---------- castomo's drawings (Andy, the kit castomo.com draws with) ----------
   A card that carries one (ui.js cardArt) gets an illustrated heading: the
   drawing at the end of the heading's row, and everything below it across the
   card's whole width - so a narrow tile never squeezes an address or a
   sentence into the drawing's shadow. Decorative throughout: a deployment
   with no drawing kit leaves `dk-art` undrawn and the card as it was. */
.card:has(> dk-art.card-art[data-on]) {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: var(--s2);
  align-content: start;
}
/* Each rule repeats the :has() so the more particular ones outrank `> *`. */
.card:has(> dk-art.card-art[data-on]) > * { grid-column: 1 / -1; }
.card:has(> dk-art.card-art[data-on]) > .card-head { grid-column: 1; grid-row: 1; align-self: start; }
.card:has(> dk-art.card-art[data-on]) > dk-art.card-art { grid-column: 2; grid-row: 1; align-self: start; margin-block: calc(var(--s1) * -1) var(--s0); }
.card > dk-art.card-art[size="md"] { --art-size: 112px; }
.card > dk-art.card-art[size="sm"] { --art-size: 76px; }
@media (max-width: 560px) {
  .card > dk-art.card-art[size="md"] { --art-size: 88px; }
  .card > dk-art.card-art[size="sm"] { --art-size: 64px; }
}

/* A dialog's drawing (the invitation, a new workspace) and a failed page's. */
dk-art.dialog-art { --art-size: 184px; margin-inline: auto; }
dk-art.error-art { margin-inline: auto; margin-block-end: var(--s2); }

/* ---------- Lists as the kit's data table (js/table.js) ---------- */

/* The search and the chips sit above their table card; the two are one block of the page. */
.table-block { display: grid; gap: var(--s2); }
.table-filters { display: flex; flex-wrap: wrap; gap: var(--s0); }
/* A row's second line (a plan, what was bought) under its name, quieter. */
.cell-sub { display: block; color: var(--ink-3); font-size: var(--t-1); font-weight: 400; overflow-wrap: anywhere; }
.row-links { display: inline-flex; flex-wrap: nowrap; align-items: center; justify-content: flex-end; gap: var(--s0); }
.cell-invoice { display: grid; justify-items: end; gap: 2px; white-space: nowrap; }
.cell-invoice bdi, .cell-lead bdi[dir="ltr"] { font-variant-numeric: tabular-nums; }

/* ---------- The overview's figures (templates/overview.html) ---------- */

/* Two currencies side by side are one long figure: it wraps rather than widening its tile. */
.kpis .stat-value, .invoice-stats .stat-value { overflow-wrap: anywhere; }
.kpis .stat-foot .link { margin-inline-start: auto; }
.card-pad { padding: 0 var(--card-pad) var(--card-pad); }
.order-total { font-weight: 650; color: var(--ink); }

/* Badges earned: small medals in a row that wraps, each with its name under it. */
.badge-strip { list-style: none; display: flex; flex-wrap: wrap; gap: var(--s2); padding: 0; margin: 0; }
.badge-strip-item { display: grid; justify-items: center; gap: var(--s0); inline-size: 6.5rem; text-align: center; color: var(--ink-2); font-size: var(--t-1); font-weight: 600; text-decoration: none; overflow-wrap: anywhere; }
.badge-strip-item .medal { --medal-size: 56px; }
.badge-strip-item:hover span, .badge-strip-item:focus-visible span { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }

/* ---------- Products: one tile per plan, lined up (§5e) ---------- */

.product-tiles > .card { display: grid; grid-template-rows: subgrid; grid-row: span 4; gap: var(--s1); }
.product-tiles > .card > .card-head { margin-block-end: 0; }
.product-tiles > .card > .card-foot { align-self: end; }
.product-badges { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--s0); }

/* ---------- Andy page components: bento grid, day / night hero, workspace setup ---------- */

/* They wear the pack's own colours, not the account's brand ramp: the teal, red and orange of castomo.com's
   drawings, so the account reads as friendly as the site does. Ink, surfaces and rules still follow the theme,
   so the dark mode keeps working; the lifted navy and plum of the characters come from the kit's --art-ink. */
.andy-set {
  --noodle-ink: var(--ink);
  --noodle-muted: var(--ink-2);
  --noodle-surface: var(--paper-2);
  --noodle-paper: var(--paper);
  --noodle-border: var(--rule);
  --noodle-accent: #f44e5d;
  --noodle-accent-2: #23b5c9;
  --noodle-accent-3: #ffa931;
  --slot-0: #23b5c9;
  --slot-1: #f44e5d;
  --slot-2: #ffa931;
  --andy-ink: var(--art-ink);
  --andy-ink-2: var(--art-ink-2);
}
/* High contrast is ink on paper and nothing else: the pack's hues give way. */
:root[data-theme^="contrast"] .andy-set { --noodle-accent: var(--ink); --noodle-accent-2: var(--ink); --noodle-accent-3: var(--ink); }

/* Products: groups by when a business needs them, each a bento grid (or a list). */
.product-groups { display: grid; gap: var(--s5); }
.product-group-head { margin-block-end: var(--s2); }
/* On Products the first group's heading also carries the tiles / list switch, at its far end on the name's line. */
.product-group-bar { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--s2); }
.product-when { max-width: 330px; padding-top: 4px; margin: 0; color: var(--ink-3); font-size: var(--t-1); font-weight: 650; letter-spacing: .06em; text-transform: uppercase; }
.product-group-head h2 { font-size: var(--t3); }

/* Tile words are the page's, so they are set here, not by the component. A heading takes the colour of its tile:
   the page's own heading ink would be black on the dark tile. The name is large and has room around it. */
.product-bento > andy-bento-tile > h3 { margin: 0 0 var(--s1); color: inherit; font-size: clamp(1.4rem, 1.2rem + .5vw, 1.7rem); line-height: 1.15; letter-spacing: -.02em; }
.product-bento > andy-bento-tile[size="big"] > h3 { font-size: clamp(1.75rem, 1.3rem + 1.2vw, 2.4rem); letter-spacing: -.03em; margin-block-end: var(--s2); }
/* The tile text is 14px: the bento tile is not inside the kit's own scale, so the size is set where it is used. */
.product-bento { --t0: 14px; }
.product-bento > andy-bento-tile > p { font-size: var(--t0); line-height: 1.55; }
.product-bento > andy-bento-tile > p + p { margin-block-start: var(--s1); }
.bento-foot { font-size: var(--t-1); font-weight: 650; }
/* No colour of its own: the line takes the tile's, which is light on the dark tile and ink on the others. */
.bento-price { font-weight: 650; opacity: .78; }
.catalogue-note { margin-block-start: var(--s3); }
.product-row { display: flex; flex: 1; align-items: center; gap: var(--s2); min-width: 0; }
.product-row .list-main small { max-width: 80ch; line-height: 1.5; }
.product-row .list-end { white-space: nowrap; }
.product-list-card + .product-list-card { margin-block-start: var(--s3); }
.product-groups:has(.product-list-card) { gap: 0; }

/* A product's own page. */
.product-page { display: grid; gap: var(--s3); max-width: 1120px; }
.product-page > .btn { justify-self: start; }
.product-price-chip { align-self: center; padding: 6px 14px; border-radius: 999px; background: var(--field); color: var(--ink); font-size: var(--t0); font-weight: 650; white-space: nowrap; }
.product-hero { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: var(--s3); align-items: stretch; }
.product-intro { display: grid; gap: var(--s2); align-content: start; font-size: var(--t1); line-height: 1.7; color: var(--ink-2); }
.product-intro p { margin: 0; max-width: 62ch; }
.product-price-tile::part(tile) { min-height: 340px; }
.product-price-tile > .product-price-label { margin: 0 0 var(--s0); font-size: var(--t-1); font-weight: 650; letter-spacing: .06em; text-transform: uppercase; }
.product-price-tile > h3 { margin: 0 0 var(--s1); color: inherit; font-size: clamp(1.75rem, 1.3rem + 1.2vw, 2.4rem); letter-spacing: -.03em; }
.product-gets, .product-for { list-style: none; display: grid; gap: var(--s2); padding: 0; margin: 0; }
/* A row that is not full stretches its tiles to the edge instead of leaving a hole (§0.13): the count of items
   differs per product and per language, so no column count would fill every row. */
.product-gets { display: flex; flex-wrap: wrap; }
.product-gets > li { flex: 1 1 min(100%, 320px); }
.product-gets li, .product-for li { display: flex; gap: var(--s1); align-items: flex-start; }
.product-for .ci { flex: none; margin-block-start: .2em; color: #23b5c9; }
/* What you get: one soft tile per item, its tick in a teal disc, every title and sentence the same size and ink. */
.product-gets li { padding: var(--s2); border-radius: 16px; background: var(--field); }
.product-gets-mark { display: grid; place-items: center; flex: none; width: 28px; height: 28px; border-radius: 50%; background: color-mix(in srgb, #23b5c9 22%, transparent); color: #0c7f90; }
.product-gets-mark .ci { --ci-size: 16px; }
:root[data-theme="dark"] .product-gets-mark { color: #5fd3e3; }
.product-gets h3 { font-size: var(--t1); margin-block-end: 4px; color: var(--ink); }
.product-gets p, .journey-text p, .product-example p, .product-faq p { margin: 0; color: var(--ink-2); line-height: 1.6; }
.product-examples { display: flex; flex-wrap: wrap; gap: var(--s2); }
.product-example { flex: 1 1 min(100%, 300px); padding: var(--s3); border-radius: 20px; background: var(--paper-2); box-shadow: inset 0 0 0 1px var(--rule); }
.product-example[data-tone] { background: radial-gradient(90% 70% at 100% 100%, color-mix(in srgb, var(--_tone) 28%, transparent), transparent 70%), color-mix(in srgb, var(--_tone) 12%, var(--paper-2)); box-shadow: none; }
.product-example[data-tone="0"] { --_tone: var(--slot-0); }
.product-example[data-tone="1"] { --_tone: var(--slot-1); }
.product-example[data-tone="2"] { --_tone: var(--slot-2); }
.product-example h3 { font-size: var(--t1); margin-block-end: var(--s1); }
.product-faq { display: grid; }
.product-faq details { border-block-start: var(--rule-w) solid var(--rule); padding-block: var(--s1); }
.product-faq details:first-child { border-block-start: 0; }
.product-faq summary { cursor: pointer; font-weight: 650; padding-block: var(--s0); }
.product-faq summary:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: 6px; }
.product-faq details p { padding-block: var(--s0) var(--s1); max-width: 70ch; }
@media (max-width: 800px) { .product-hero { grid-template-columns: minmax(0, 1fr); } }

/* Workspaces: the hero is a rounded block of its own; the setup is as wide as its two columns need. */
.ws-hero { margin-block-end: var(--s3); border-radius: 24px; overflow: clip; }
.workspace-setup { max-width: 1040px; }

/* ---------- Profile ---------- */

/* The picture at 96 px beside its buttons; the kit's .avatar takes its size from --size. */
.profile-picture { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.profile-avatar .avatar { --size: 96px; font-size: var(--t2); }
.profile-avatar .avatar img { border-radius: 50%; }

/* What a visitor is offered, one group at a time; each tick shows the value under its name. */
.profile-ticks fieldset { padding-block-end: var(--s2); border-block-end: var(--rule-w) solid var(--rule); }
.profile-ticks fieldset:last-child { border-block-end: 0; padding-block-end: 0; }
.profile-ticks .check small { display: block; overflow-wrap: anywhere; }
.profile-preview { overflow-wrap: anywhere; }

/* ---------- Boards ---------- */

.share-link .list-main { min-inline-size: 0; }
.dialog-body > .list { margin-block-end: var(--s1); }

/* ---------- Support ---------- */

.support-message summary { cursor: pointer; color: var(--ink-3); font-size: var(--t-1); }
.support-message p { white-space: pre-wrap; overflow-wrap: anywhere; margin-block-start: var(--s0); color: var(--ink-2); }
.support-list > .card { block-size: 100%; }

/* ---------- One job card (record page: heading, then 8 + 4 columns) ---------- */

.jc-head h1 { overflow-wrap: anywhere; }
.jc-chips { display: flex; flex-wrap: wrap; gap: var(--s0); margin-block-start: var(--s1); }
.jc-h { font-size: var(--t-1); color: var(--ink-3); font-weight: 650; }

/* The jobs, numbered large at the start of each, the way castomo.com prints them. */
.jc-jobs { list-style: none; display: grid; gap: var(--s2); padding: 0; margin: 0; }
.jc-job { display: grid; grid-template-columns: 3rem minmax(0, 1fr); gap: var(--s1); padding-block-start: var(--s2); border-block-start: var(--rule-w) solid var(--rule); }
.jc-job:first-child { padding-block-start: 0; border-block-start: 0; }
.jc-job-n { font-size: var(--t3); font-weight: 750; line-height: 1; color: var(--accent-ink); font-variant-numeric: tabular-nums; }
.jc-job-body { display: grid; gap: var(--s0); min-inline-size: 0; }
.jc-job-body h3 { font-size: var(--t1); }
.jc-job-tool { color: var(--ink-3); font-size: var(--t-1); }
.jc-job-tool b { color: var(--ink-2); }
.jc-job-then b { font-weight: 650; }

/* Twelve weeks: a label column and twelve cells per job. Grid columns follow the
   page's direction, so week 1 stands at the start in a right-to-left language too. */
.jc-gantt { display: grid; gap: 4px; }
.jc-g-row { display: grid; grid-template-columns: 2.5rem repeat(12, minmax(0, 1fr)); gap: 3px; align-items: center; }
.jc-g-head { color: var(--ink-3); font-size: var(--t-1); text-align: center; font-variant-numeric: tabular-nums; }
.jc-g-label { font-weight: 650; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.jc-g-c { block-size: 14px; border-radius: 4px; background: var(--field); }
.jc-g-c.is-on { background: var(--accent); }
.jc-steps { list-style: none; display: grid; gap: var(--s1); padding: 0; margin: 0; }
.jc-steps > li { display: grid; grid-template-columns: 6.5rem minmax(0, 1fr); gap: 0 var(--s1); }
.jc-steps > li > b { grid-row: span 2; font-weight: 650; }
.jc-step-job { color: var(--ink-3); font-size: var(--t-1); }
@media (max-width: 400px) {
  .jc-steps > li { grid-template-columns: minmax(0, 1fr); }
  .jc-steps > li > b { grid-row: auto; }
  .jc-g-row { grid-template-columns: 2rem repeat(12, minmax(0, 1fr)); gap: 2px; }
}
.jc-goals { display: grid; gap: var(--s0); padding-inline-start: 1.1em; margin: 0; }
.jc-aside { margin: 0; padding-inline-start: var(--s2); border-inline-start: 3px solid var(--accent); color: var(--ink-2); font-style: italic; }

/* On paper: the card and nothing of the page around it. */
@media print {
  .side, .top, .tabbar, .page-actions, .skip-link, dk-art, .agent-fab, .toast-region { display: none !important; }
  .app { display: block; }
  .main, .page { padding: 0; }
  .split { display: block; }
  .split > * + * { margin-block-start: var(--s2); }
  .card { break-inside: avoid; box-shadow: none; border: var(--rule-w) solid var(--rule); }
  .jc-g-c.is-on { print-color-adjust: exact; -webkit-print-color-adjust: exact; }
}

/* A column of cards beside a taller one keeps its cards their own height. */
.split > .stack { align-content: start; }

/* On a phone a table row is a card (the kit's 720 px step): the lead cell stacks
   its name over its second line, and a cell of several badges keeps them together. */
.cell-badges { display: inline-flex; flex-wrap: wrap; gap: var(--s0); justify-content: flex-end; }
@media (max-width: 720px) {
  .table td.cell-lead { flex-direction: column; align-items: flex-start; gap: 2px; }
  .table td.row-actions .cell-invoice { justify-items: end; }
}

/* ---------- How it works: a journey (a product's steps, each with its drawing) ---------- */

/* A numbered rail down the left and one card per step. Each step's drawing waits as a silhouette and
   colours in, one step after the other, whenever the tab is opened (the panel is hidden until then, so the
   animation starts afresh on every opening). Without motion the steps simply stand there in colour. */
.journey { list-style: none; display: grid; margin: 0; padding: 0; counter-reset: journey; }
.journey-step { position: relative; display: grid; grid-template-columns: 44px minmax(0, 1fr); column-gap: var(--s2); padding-block-end: var(--s2); }
.journey-step:last-child { padding-block-end: 0; }
.journey-step:not(:last-child)::before { content: ""; position: absolute; inset-inline-start: 21px; inset-block: 48px 0; width: 2px; background: var(--rule); }
.journey-mark { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; background: #ffa931; color: #1a1a2e; font-weight: 750; font-size: var(--t1); box-shadow: 0 0 0 5px var(--paper-2); position: relative; }
.journey-card { display: grid; grid-template-columns: 112px minmax(0, 1fr); gap: var(--s2); align-items: center; padding: var(--s2); border-radius: 20px; background: var(--field); }
.journey-art { width: 112px; border-radius: 14px; background: var(--paper-2); }
.journey-num { margin: 0 0 4px; color: var(--ink-3); font-size: var(--t-1); font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.journey-text h3 { margin: 0 0 6px; font-size: var(--t2); line-height: 1.25; letter-spacing: -.015em; color: var(--ink); }
.journey-text p:last-child { margin: 0; color: var(--ink-2); line-height: 1.6; max-width: 62ch; }
@media (prefers-reduced-motion: no-preference) {
  .journey-step { animation: journey-in .5s cubic-bezier(.2, .8, .2, 1) both; animation-delay: calc(var(--i) * 140ms); }
  .journey-art::part(art) { animation: journey-colour .7s ease-out both; animation-delay: calc(var(--i) * 140ms + 200ms); }
  .journey-mark { animation: journey-pop .5s cubic-bezier(.34, 1.56, .64, 1) both; animation-delay: calc(var(--i) * 140ms); }
}
@keyframes journey-in { from { opacity: 0; transform: translateY(14px); } }
@keyframes journey-colour { from { filter: brightness(0); opacity: .12; } }
@keyframes journey-pop { from { transform: scale(.6); } }
@media (max-width: 640px) {
  .journey-step { grid-template-columns: 32px minmax(0, 1fr); column-gap: var(--s1); }
  .journey-mark { width: 32px; height: 32px; font-size: var(--t0); }
  .journey-step:not(:last-child)::before { inset-inline-start: 15px; inset-block-start: 36px; }
  .journey-card { grid-template-columns: 72px minmax(0, 1fr); gap: var(--s1); padding: var(--s1); }
  .journey-art { width: 72px; }
}

/* ---------- Services: the ones in use, then the rest of the family ---------- */
.service-sections { display: grid; gap: var(--s5); }
.service-section .product-group-head p { margin: 4px 0 0; }

/* ---------- Offers: the planner, an offer's lines and its selection, placed job cards ---------- */
.offer-planner { margin-block-end: var(--s3); }
.offer-form .textarea { min-block-size: 8.5rem; }
.offer-mine { margin-block-start: var(--s2); color: var(--ink-2); }
.offer-summary, .offer-brief { margin: 0; color: var(--ink-2); line-height: 1.6; overflow-wrap: anywhere; white-space: pre-line; }
.offer-part + .offer-part { margin-block-start: var(--s3); }
.offer-part-title { margin: 0; font-size: var(--t2); }
.offer-part-sub { margin: 2px 0 var(--s1); color: var(--ink-3); font-size: var(--t-1); }
/* A part not drawn yet: a spinner and two shimmering lines where its products will be. */
.offer-preparing { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--s1) var(--s1); align-items: center; padding: var(--s2); border: var(--rule-w) dashed var(--rule); border-radius: var(--r2, 12px); color: var(--ink-2); }
.offer-preparing > i { animation: dk-spin 1.1s linear infinite; }
.offer-preparing > .skeleton { grid-column: 1 / -1; }
.offer-preparing > .skeleton:last-child { inline-size: 60%; }
.offer-preparing.is-failed { grid-template-columns: auto minmax(0, 1fr) auto; border-style: solid; }
@media (prefers-reduced-motion: reduce) { .offer-preparing > i { animation: none; } }
.offer-lines { list-style: none; display: grid; gap: 0; padding: 0; margin: 0; }
.offer-line { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: var(--s2); align-items: start; padding-block: var(--s2); border-block-start: var(--rule-w) solid var(--rule); transition: opacity .15s ease; }
.offer-line:first-child { border-block-start: 0; padding-block-start: 0; }
.offer-lines-static .offer-line { grid-template-columns: minmax(0, 1fr) auto; }
.offer-line.is-off { opacity: .55; }
.offer-line-tick { display: grid; place-items: center; inline-size: 44px; block-size: 44px; margin: -10px; cursor: pointer; }
.offer-line-tick input { inline-size: 20px; block-size: 20px; accent-color: var(--accent); cursor: pointer; }
.offer-line-body { display: grid; gap: var(--s0); min-inline-size: 0; }
.offer-line-body h3 { font-size: var(--t1); }
.offer-line-body p { margin: 0; color: var(--ink-2); overflow-wrap: anywhere; }
.offer-line-outcome { display: flex; gap: var(--s0); align-items: flex-start; color: var(--ink); }
.offer-line-outcome .ci { flex: none; margin-block-start: 3px; color: var(--accent-ink); }
.offer-line-figures { display: grid; justify-items: end; gap: 2px; text-align: end; white-space: nowrap; }
.offer-line-price { font-size: var(--t1); font-variant-numeric: tabular-nums; }
.offer-line-when { color: var(--ink-3); font-size: var(--t-1); }
.offer-qty { max-inline-size: 6.5rem; font-variant-numeric: tabular-nums; }
.offer-total { font-size: var(--t2); color: var(--accent-ink); font-variant-numeric: tabular-nums; }
.offer-selection { position: sticky; inset-block-start: var(--s2); }
.placed-cards { display: grid; gap: var(--s2); margin-block-end: var(--s4); }
.placed-head { display: grid; gap: 2px; margin-block-end: var(--s1); }
.placed-head h2 { font-size: var(--t2); }
.placed-head p { margin: 0; }
@media (max-width: 640px) {
  .offer-line { grid-template-columns: auto minmax(0, 1fr); }
  .offer-lines-static .offer-line { grid-template-columns: minmax(0, 1fr); }
  .offer-line-figures { grid-column: 2; justify-items: start; text-align: start; grid-auto-flow: column; gap: var(--s1); align-items: baseline; }
  .offer-lines-static .offer-line-figures { grid-column: 1; }
  .offer-selection { position: static; }
}
@media print {
  .offer-selection { position: static; }
}
