/*
 * PizzaLogic design layer (redesign A "Polished", epic pl-5b7f.1)
 *
 * SHARED by web and app. Source of truth: apps/web/css/design.css.
 * apps/mobile/src/css/design.css is a copy made by `npm run design:sync`
 * (the unit tests fail if the two differ). Never edit the mobile copy.
 *
 * Load order: styles.css -> design.css -> (app only) mobile.css.
 * styles.css keeps layout and legacy rules; this file owns the theme
 * tokens and the refined look of shared components.
 *
 * Reference mockup: docs/design/2026-10-redesign/refinements/01-polished/mockup.html
 * Spec: docs/design/2026-10-redesign/refinements/IMPLEMENTATION.md
 */

/* ------------------------------------------------------------------ */
/* 1. Theme tokens                                                     */
/* ------------------------------------------------------------------ */
/*
 * Existing token names keep working (styles.css, blog.css, mobile.css use
 * them). New tokens:
 *   --surface-2        quiet fill: tips, sub-panels, input groups
 *   --muted            secondary text (helper lines, captions, times)
 *   --tint             selected-state fill, chips, quick-reference tiles
 *   --accent-ink       accent for TEXT and icon strokes (AA on --card-bg)
 *   --on-accent        text/icons on a solid --primary-color fill
 *   --icon-2           the warm second colour inside two-tone icons
 *   --icon-fill-opacity
 *   --card-shadow, --radius-card, --radius-control, --radius-callout
 *   --dock-bg          quick-reference bar / tab bar background
 *   --control-border   outline of form controls (inputs, selects, steppers,
 *                      unchecked checkboxes): >= 3:1 on --card-bg, --input-bg
 *                      and --surface-2 (WCAG 1.4.11). --border-color stays
 *                      for dividers and card edges.
 * Headings (--card-heading) are now dark text, not the accent colour; the
 * accent lives in the icon beside them.
 */
:root {
    --primary-start: #536ae4;
    --primary-end: #7650ae;
    --primary-color: #5a55d2;
    --primary-hover: #4b45c2;
    --card-bg: #ffffff;
    --card-text: #24233a;
    --card-heading: #24233a;
    --label-color: #3d3c52;
    --border-color: #e1e1ec;
    --control-border: #8b8aa4;
    /* pl-c2xw: legacy name used across mobile.css and the blend % input,
       never defined, so those borders didn't render. Follows the theme's
       hairline; real inputs get --control-border from section 9. */
    --input-border: var(--border-color);
    /* pl-idwe: legacy names used in styles.css / mobile.css that were never
       defined (resolved to inherited colour, ignoring the theme). Aliased to
       existing tokens so they follow every theme. */
    --input-label: var(--label-color);
    --text-color: var(--card-text);
    --text-secondary: var(--muted);
    --text-muted: var(--muted);
    --input-text: var(--card-text);
    --button-bg: var(--primary-color);
    --primary: var(--primary-color);
    --danger: var(--alert-danger-border);
    --danger-bg: var(--alert-danger-bg);
    --danger-text: var(--alert-danger-text);
    --accent-primary: var(--primary-color);
    --border-light: #ececf4;
    --input-bg: #ffffff;
    --step-title: #24233a;
    --step-text: #3d3c52;
    --tip-bg: #f5f5fa;
    --header-text: #ffffff;

    --surface-2: #f5f5fa;
    --muted: #66657b;
    --tint: #eeeefc;
    --accent-ink: #4b45c2;
    --on-accent: #ffffff;
    --icon-2: #ffb547;
    --icon-fill-opacity: 0.75;
    --card-shadow: 0 4px 18px rgba(30, 20, 80, 0.14);
    --dock-bg: #ffffff;
    --radius-card: 16px;
    --radius-control: 12px;
    --radius-callout: 10px;

    --alert-info-bg: #eef3fd;
    --alert-info-border: #4f7fd8;
    --alert-info-text: #22344f;
    --alert-warning-bg: #fdf6e7;
    --alert-warning-border: #b57c10;
    --alert-warning-text: #4d3a10;
    --alert-danger-bg: #fdf0f0;
    --alert-danger-border: #d04545;
    --alert-danger-text: #7d2222;
    --alert-success-bg: #eef8f1;
    --alert-success-border: #3f9a5c;
    --alert-success-text: #1f5132;
}

[data-theme='warm'] {
    --primary-start: #9a5229;
    --primary-end: #ad6236;
    --primary-color: #a84c10;
    --primary-hover: #8f400c;
    --card-bg: #fdf8f0;
    --card-text: #3d3127;
    --card-heading: #3d3127;
    --label-color: #5a4b3e;
    --border-color: #eadcca;
    --control-border: #9c8672;
    --border-light: #f1e7da;
    --input-bg: #fffcf8;
    --step-title: #3d3127;
    --step-text: #5a4b3e;
    --tip-bg: #f6eee2;
    --header-text: #ffffff;

    --surface-2: #f6eee2;
    --muted: #73645a;
    --tint: #f5e6d6;
    --accent-ink: #9a450d;
    --on-accent: #ffffff;
    --icon-2: #f5c04a;
    --icon-fill-opacity: 0.8;
    --card-shadow: 0 4px 18px rgba(80, 30, 0, 0.16);
    --dock-bg: #fdf8f0;

    --alert-info-bg: #ebf3f1;
    --alert-info-border: #3f7f78;
    --alert-info-text: #22403c;
    --alert-warning-bg: #fbf0dc;
    --alert-warning-border: #b97a12;
    --alert-warning-text: #4c3610;
    --alert-danger-bg: #fbeee8;
    --alert-danger-border: #b7410e;
    --alert-danger-text: #6e2708;
    --alert-success-bg: #eef4ea;
    --alert-success-border: #5f8752;
    --alert-success-text: #34492b;
}

[data-theme='dark'] {
    --primary-start: #0a0e13;
    --primary-end: #0e141b;
    --primary-color: #2fb9dc;
    --primary-hover: #5cd0ee;
    --card-bg: #141b23;
    --card-text: #e1e7ed;
    --card-heading: #e9eef3;
    --label-color: #b4c0cb;
    --border-color: #263240;
    --control-border: #5e7085;
    --border-light: #1c2631;
    --input-bg: #0f151c;
    --step-title: #e9eef3;
    --step-text: #c3ccd5;
    --tip-bg: #1b242e;
    --header-text: #e1e7ed;

    --surface-2: #1b242e;
    --muted: #93a0ad;
    --tint: #13303b;
    --accent-ink: #5cd0ee;
    --on-accent: #04202a;
    --icon-2: #ffb547;
    --icon-fill-opacity: 0.7;
    --card-shadow: 0 4px 18px rgba(0, 0, 0, 0.4);
    --dock-bg: #111820;

    --alert-info-bg: #132634;
    --alert-info-border: #4aa3d8;
    --alert-info-text: #cfe3f1;
    --alert-warning-bg: #2c2414;
    --alert-warning-border: #d9a032;
    --alert-warning-text: #f0dfbd;
    --alert-danger-bg: #2c1515;
    --alert-danger-border: #e06060;
    --alert-danger-text: #f3c9c9;
    --alert-success-bg: #12261a;
    --alert-success-border: #3fae67;
    --alert-success-text: #c4ebd1;
}

[data-theme='cool'] {
    --primary-start: #136f88;
    --primary-end: #1b7f9b;
    --primary-color: #137290;
    --primary-hover: #0f6681;
    --card-bg: #ffffff;
    --card-text: #1f2f36;
    --card-heading: #1f2f36;
    --label-color: #33464e;
    --border-color: #dbe8ec;
    --control-border: #78909a;
    --border-light: #e9f2f5;
    --input-bg: #ffffff;
    --step-title: #1f2f36;
    --step-text: #33464e;
    --tip-bg: #f2f8fa;
    --header-text: #ffffff;

    --surface-2: #f2f8fa;
    --muted: #5a6c74;
    --tint: #e3f2f6;
    --accent-ink: #0f6681;
    --on-accent: #ffffff;
    --icon-2: #ff8a6b;
    --icon-fill-opacity: 0.75;
    --card-shadow: 0 4px 18px rgba(0, 50, 70, 0.15);
    --dock-bg: #ffffff;

    --alert-info-bg: #eaf3fb;
    --alert-info-border: #3d7fc2;
    --alert-info-text: #1e3550;
    --alert-warning-bg: #fdf6e7;
    --alert-warning-border: #b57c10;
    --alert-warning-text: #4d3a10;
    --alert-danger-bg: #fdf0f0;
    --alert-danger-border: #d04545;
    --alert-danger-text: #7d2222;
    --alert-success-bg: #eaf7f0;
    --alert-success-border: #2f9466;
    --alert-success-text: #1c4d36;
}

[data-theme='light'] {
    --primary-start: #f4f6f9;
    --primary-end: #e3e7ed;
    --primary-color: #5560d0;
    --primary-hover: #4a54c2;
    --card-bg: #ffffff;
    --card-text: #262838;
    --card-heading: #262838;
    --label-color: #3f4254;
    --border-color: #e0e3ea;
    --control-border: #878b9e;
    --border-light: #eceef3;
    --input-bg: #ffffff;
    --step-title: #262838;
    --step-text: #3f4254;
    --tip-bg: #f5f6f9;
    --header-text: #2c2f3d;

    --surface-2: #f5f6f9;
    --muted: #676a7c;
    --tint: #eef0fc;
    --accent-ink: #4a54c2;
    --on-accent: #ffffff;
    --icon-2: #ffb547;
    --icon-fill-opacity: 0.75;
    --card-shadow: 0 2px 10px rgba(20, 30, 60, 0.08);
    --dock-bg: #ffffff;

    --alert-info-bg: #eef3fd;
    --alert-info-border: #4f7fd8;
    --alert-info-text: #22344f;
    --alert-warning-bg: #fdf6e7;
    --alert-warning-border: #b57c10;
    --alert-warning-text: #4d3a10;
    --alert-danger-bg: #fdf0f0;
    --alert-danger-border: #d04545;
    --alert-danger-text: #7d2222;
    --alert-success-bg: #eef8f1;
    --alert-success-border: #3f9a5c;
    --alert-success-text: #1f5132;
}

/* ------------------------------------------------------------------ */
/* 2. Icons (Lucide sprite, two-tone)                                  */
/* ------------------------------------------------------------------ */
/*
 * Markup: icon('pizza') in JS (packages/core/src/icons.js) or
 * Icons::svg('pizza') in PHP. Stroke = currentColor (defaults to the accent
 * ink), fill = the warm --icon-2. Control glyphs get .icon-line (no fill).
 * Inside a solid accent surface set `color: inherit` on the icon.
 */
.icon {
    display: inline-block;
    width: 1.25em;
    height: 1.25em;
    flex: none;
    vertical-align: -0.24em;
    color: var(--accent-ink);
    stroke: currentColor;
    stroke-width: 1.75;
    stroke-linecap: round;
    stroke-linejoin: round;
    fill: var(--icon-2);
    fill-opacity: var(--icon-fill-opacity);
    overflow: visible;
}

.icon-line {
    fill: none;
}

/* ------------------------------------------------------------------ */
/* 3. Info boxes: full 1px border in the darker colour, no left bar    */
/* ------------------------------------------------------------------ */
.alert {
    border: 1px solid var(--alert-info-border);
    border-radius: var(--radius-callout);
    padding: 10px 12px;
}

.alert-info {
    border-color: var(--alert-info-border);
}

.alert-warning {
    border-color: var(--alert-warning-border);
}

.alert-danger {
    border-color: var(--alert-danger-border);
}

.alert-success {
    border-color: var(--alert-success-border);
}

/* ------------------------------------------------------------------ */
/* 4. New shared hooks (markup on both platforms uses these)           */
/* ------------------------------------------------------------------ */
/* Icons sit OUTSIDE the element that carries data-i18n (the app's i18n
   sweep replaces textContent): <h2 class="card-title">ICON<span data-i18n>..</span></h2> */

/* Brand header: centred logo + wordmark on the page background */
.brand {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    margin: 6px 0 14px;
    color: var(--header-text);
    text-align: left;
}
.brand-logo {
    width: 47px;
    height: 47px;
    border-radius: 12px;
    flex: none;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
}
.brand-name {
    display: grid;
    line-height: 1.15;
    min-width: 0;
}
.brand-wordmark {
    font-size: 1.65em;
    font-weight: 700;
    letter-spacing: -0.01em;
}
.brand-sub {
    font-size: 1.07em;
    opacity: 0.85;
}

/* Card title with icon */
.card-title {
    display: flex;
    align-items: center;
    gap: 9px;
    color: var(--card-heading);
    font-weight: 700;
    text-wrap: balance;
}
.card-title .title-ic,
.title-ic {
    width: 20px;
    height: 20px;
}

/* Icons inside labels, tips, callouts, buttons */
.label-ic {
    width: 17px;
    height: 17px;
    margin-right: 6px;
    vertical-align: -0.24em;
}
.tip-ic {
    width: 16px;
    height: 16px;
}
.alert:has(> .alert-ic) {
    display: flex;
    gap: 10px;
    align-items: flex-start;
}
.alert-ic {
    width: 18px;
    height: 18px;
    margin-top: 1px;
}
.alert-info > .alert-ic {
    color: var(--alert-info-border);
}
.alert-warning > .alert-ic {
    color: var(--alert-warning-border);
}
.alert-danger > .alert-ic {
    color: var(--alert-danger-border);
}
.alert-success > .alert-ic {
    color: var(--alert-success-border);
}
/* Time preset icon (both platforms) */
.time-option .time-ic {
    display: block;
    width: 22px;
    height: 22px;
    margin-bottom: 4px;
}

/* Callout icons take a light tint of the callout's own colour, not the warm
   --icon-2 (warm fill inside a blue box reads as a blob). */
.alert-ic,
.alert .icon {
    fill: currentColor;
    fill-opacity: 0.14;
}

.btn-ic {
    width: 18px;
    height: 18px;
}

/* Icon-only button (info, close, lock): 44px target, visual icon smaller */
.icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    margin: -12px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--accent-ink);
    cursor: pointer;
}

/* Full-width primary call to action */
.btn-block {
    display: flex;
    width: 100%;
    justify-content: center;
}

/* Style slider hint: dots + arrows under the scroller */
.style-hint {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin-top: 8px;
}
.style-dots {
    display: flex;
    gap: 5px;
    align-items: center;
}
.style-dots i {
    width: 6px;
    height: 6px;
    border-radius: 3px;
    background: var(--border-color);
    transition:
        width 0.2s,
        background 0.2s;
}
.style-dots i.on {
    width: 14px;
    background: var(--primary-color);
}
.style-hint .hint-arrow {
    width: 16px;
    height: 16px;
    color: var(--muted);
    transition: opacity 0.2s;
}
.style-hint .hint-arrow.off {
    opacity: 0.25;
}

/* Collapsible section header (e.g. Nutrition estimate) */
.collapse-head {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}
.collapse-caret {
    width: 18px;
    height: 18px;
    color: var(--muted);
    transition: transform 0.2s;
}
.is-collapsed .collapse-caret {
    transform: rotate(-90deg);
}
.is-collapsed .collapse-body {
    display: none;
}

/* Empty state */
.empty-state-icon {
    display: inline-grid;
    place-items: center;
    width: 64px;
    height: 64px;
    border-radius: 50%;
    background: var(--tint);
}
.empty-state-icon .icon {
    width: 32px;
    height: 32px;
}

/* Inline icons for text that comes from translated strings (no markup hook):
   video links inside tips, and the equipment-warning step title. */
.video-link::before,
.step-warning .step-title::before {
    content: '';
    display: inline-block;
    width: 1.1em;
    height: 1.1em;
    margin-right: 0.3em;
    vertical-align: -0.2em;
    background: currentColor;
    -webkit-mask: var(--mask-icon) center / contain no-repeat;
    mask: var(--mask-icon) center / contain no-repeat;
}
.video-link::before {
    --mask-icon: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%20%3E%20%3Ccircle%20cx=%2212%22%20cy=%2212%22%20r=%2210%22%20/%3E%20%3Cpolygon%20points=%2210%208%2016%2012%2010%2016%2010%208%22%20/%3E%20%3C/svg%3E');
}
.step-warning .step-title::before {
    --mask-icon: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%20%3E%20%3Cpath%20d=%22m21.73%2018-8-14a2%202%200%200%200-3.48%200l-8%2014A2%202%200%200%200%204%2021h16a2%202%200%200%200%201.73-3%22%20/%3E%20%3Cpath%20d=%22M12%209v4%22%20/%3E%20%3Cpath%20d=%22M12%2017h.01%22%20/%3E%20%3C/svg%3E');
}

/* Keyboard focus */
:where(button, a, input, select, textarea, [role='radio'], [tabindex]):focus-visible {
    outline: 2px solid var(--accent-ink);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        transition-duration: 0.01ms !important;
        animation-duration: 0.01ms !important;
    }
}

/* ------------------------------------------------------------------ */
/* 5. Shared components restyled (work package C owns this section)    */
/* ------------------------------------------------------------------ */
/* WP-C:BEGIN */
/* ---- 5.1 Base: page, cards, headings, labels --------------------- */
body {
    background: linear-gradient(165deg, var(--primary-start) 0%, var(--primary-end) 100%);
    background-attachment: fixed;
}
a {
    color: var(--accent-ink);
}
.card {
    background: var(--card-bg);
    border-radius: var(--radius-card);
    padding: 18px 16px;
    box-shadow: var(--card-shadow);
    margin-bottom: 14px;
}
.card h2,
.card-title {
    color: var(--card-heading);
    font-size: 1.286em;
    font-weight: 700;
    line-height: 1.25;
    margin-bottom: 14px;
}
.card h2 > .icon,
.card-title > .icon {
    width: 20px;
    height: 20px;
}
label {
    color: var(--label-color);
    font-size: 0.964em;
    font-weight: 600;
    margin-bottom: 6px;
}
/* inline styles in the markup colour some labels grey; keep them on-token */
label[style*='color'] {
    color: var(--label-color) !important;
}
.form-group {
    margin-bottom: 14px;
}
.form-grid-2col {
    gap: 14px;
}
.form-grid-2col .form-group {
    margin-bottom: 0;
}
.form-hint {
    color: var(--muted);
    font-size: 0.893em;
}
.label-with-info {
    gap: 6px;
}
:where(label, .card-title, h2) .icon {
    vertical-align: -0.24em;
}

/* ---- 5.2 Mode toggle --------------------------------------------- */
.mode-toggle {
    background: color-mix(in srgb, var(--header-text) 16%, transparent);
    border: 1px solid color-mix(in srgb, var(--header-text) 30%, transparent);
    border-radius: 999px;
    padding: 3px;
}
.mode-btn {
    padding: 7px 22px;
    border-radius: 999px;
    color: var(--header-text);
    font-size: 1em;
    transition:
        background 0.2s,
        color 0.2s;
}
.mode-btn.active {
    background: var(--card-bg);
    color: var(--accent-ink);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
}
.mode-btn:not(.active):hover {
    background: color-mix(in srgb, var(--header-text) 10%, transparent);
}
.mode-toggle-wrapper {
    align-items: center;
}
.mode-hint {
    color: color-mix(in srgb, var(--header-text) 85%, transparent);
    font-size: 0.893em;
    text-align: center;
}

/* ---- 5.3 Style cards + scroller ---------------------------------- */
.style-scroller {
    margin-bottom: 0;
}
.style-grid {
    gap: 10px;
    padding: 2px 16px 6px;
    margin-inline: -16px;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: 16px;
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 36px), transparent);
    mask-image: linear-gradient(90deg, #000 calc(100% - 36px), transparent);
}
/* edge fade: JS adds .scrolled (something to the left) and .at-end (nothing to the right) */
.style-grid.scrolled,
.style-scroller.scrolled .style-grid {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 36px, #000 calc(100% - 36px), transparent);
    mask-image: linear-gradient(90deg, transparent, #000 36px, #000 calc(100% - 36px), transparent);
}
.style-grid.at-end,
.style-scroller.at-end .style-grid {
    -webkit-mask-image: none;
    mask-image: none;
}
.style-grid.scrolled.at-end,
.style-scroller.scrolled.at-end .style-grid {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 36px);
    mask-image: linear-gradient(90deg, transparent, #000 36px);
}
/* the hint (dots and arrows) replaces the overlay arrow buttons */
.card:has(.style-hint) .scroll-arrow {
    display: none;
}
.style-card {
    position: relative;
    min-width: 150px;
    max-width: 230px;
    padding: 12px 30px 12px 14px;
    border: 1.5px solid var(--border-color);
    border-radius: var(--radius-control);
    background: var(--card-bg);
    text-align: left;
    scroll-snap-align: start;
}
.style-card:hover {
    border-color: var(--primary-color);
}
.style-card.selected,
.style-card[aria-checked='true'] {
    border-color: var(--primary-color);
    background: var(--tint);
}
.style-card-name,
.style-card-desc {
    /* the base sheet keeps these on one line; long names (Modern Neapolitan
       (Canotto)) at large Font size or in long languages ran past the card */
    white-space: normal;
    overflow-wrap: break-word;
    text-wrap: balance;
}
.style-card-name {
    color: var(--card-text);
    font-size: 1.07em;
    font-weight: 650;
    line-height: 1.25;
    margin-bottom: 2px;
}
.style-card-desc {
    color: var(--muted);
    font-size: 0.893em;
    line-height: 1.25;
}
/* check mark on the selected card (a mask, so it follows the theme) */
.style-card.selected::after {
    content: '';
    position: absolute;
    top: 9px;
    right: 9px;
    width: 16px;
    height: 16px;
    background: var(--accent-ink);
    -webkit-mask: var(--check-mask) center / contain no-repeat;
    mask: var(--check-mask) center / contain no-repeat;
}
.style-card:has(.style-check)::after {
    display: none;
}
:root {
    --check-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
    --bulb-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5'/%3E%3Cpath d='M9 18h6'/%3E%3Cpath d='M10 22h4'/%3E%3C/svg%3E");
}
.style-card .style-check {
    position: absolute;
    top: 8px;
    right: 8px;
    width: 16px;
    height: 16px;
    color: var(--accent-ink);
}
.style-card:not(.selected) .style-check {
    display: none;
}
@media (min-width: 500px) {
    .style-card {
        min-width: 150px;
        padding: 12px 30px 12px 14px;
    }
    .style-card-name {
        font-size: 1.07em;
    }
    .style-card-desc {
        font-size: 0.893em;
    }
}

/* ---- 5.4 Time presets -------------------------------------------- */
.time-options {
    gap: 10px;
}
.time-option {
    align-items: flex-start;
    justify-content: flex-start;
    gap: 1px;
    min-height: 0;
    padding: 12px;
    border: 1.5px solid var(--border-color);
    border-radius: var(--radius-control);
    background: var(--card-bg);
    text-align: left;
    min-width: 0;
}
.time-option:hover {
    border-color: var(--primary-color);
}
.time-option.selected,
.time-option[aria-checked='true'] {
    border-color: var(--primary-color);
    background: var(--tint);
}
.time-option > .icon {
    width: 18px;
    height: 18px;
    margin-bottom: 4px;
}
.time-option-primary {
    color: var(--card-text);
    font-size: 1.07em;
    font-weight: 650;
}
.time-option-secondary {
    color: var(--accent-ink);
    font-size: 0.893em;
    font-weight: 600;
    margin-top: 0;
}
.time-option-detail {
    color: var(--muted);
    font-size: 0.857em;
    opacity: 1;
    margin-top: 0;
}
.fermentation-note {
    margin-top: 12px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--muted);
    font-size: 0.929em;
    text-align: center;
}
.fermentation-note:empty {
    display: none;
}

/* ---- 5.5 Steppers ------------------------------------------------ */
.stepper .stepper-value {
    border: 0;
    border-radius: 0;
}
.stepper {
    flex: none;
    height: 46px;
    border: 1.5px solid var(--border-color);
    border-radius: var(--radius-control);
    background: var(--input-bg);
}
.stepper .stepper-btn {
    width: 46px;
    height: auto;
    align-self: stretch;
    border-radius: 0;
    background: var(--primary-color);
    color: var(--on-accent);
    font-size: 1.5em;
    font-weight: 500;
    line-height: 1;
    transition: background 0.15s;
}
.stepper .stepper-btn:hover {
    background: var(--primary-hover);
    opacity: 1;
}
.stepper .stepper-btn:active {
    opacity: 1;
    background: var(--primary-hover);
}
.stepper-value {
    height: 100%;
    background: transparent;
    color: var(--card-text);
    font-size: 1.214em;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    padding: 0 6px;
}
.stepper-value:focus {
    background: var(--surface-2);
}
.stepper-value::placeholder {
    color: var(--muted);
}
/* the unit sits beside the value, the pair centred between the buttons */
.stepper:has(.stepper-unit) {
    justify-content: center;
}
.stepper:has(.stepper-unit) .stepper-btn[data-action='dec'] {
    margin-right: auto;
}
.stepper:has(.stepper-unit) .stepper-btn[data-action='inc'] {
    margin-left: auto;
}
.stepper:has(.stepper-unit) .stepper-value {
    flex: none;
    width: 3.4em;
    min-width: 0;
    padding-right: 3px;
    text-align: right;
}
.stepper-unit {
    position: static;
    transform: none;
    padding-right: 4px;
    color: var(--muted);
    font-size: 0.964em;
    font-variant-numeric: tabular-nums;
}
.input-with-icon {
    display: block;
}
.input-icon {
    display: none;
}

/* ---- 5.6 Selects, inputs with units ------------------------------ */
select {
    height: 46px;
    padding: 0 34px 0 14px;
    border: 1.5px solid var(--border-color);
    border-radius: var(--radius-control);
    background-color: var(--input-bg);
    color: var(--card-text);
    font-size: 1.07em;
    -webkit-appearance: none;
    appearance: none;
    background-image:
        linear-gradient(45deg, transparent 50%, var(--muted) 50%),
        linear-gradient(135deg, var(--muted) 50%, transparent 50%);
    background-position:
        calc(100% - 19px) 50%,
        calc(100% - 13px) 50%;
    background-size:
        6px 6px,
        6px 6px;
    background-repeat: no-repeat;
}
select:focus,
input[type='number']:focus {
    border-color: var(--primary-color);
}
input[type='number'] {
    border-radius: var(--radius-control);
}
input[type='number']:where(:not(.stepper-value, .blend-pct-input)) {
    height: 46px;
    border: 1.5px solid var(--border-color);
    padding: 0 14px;
    font-size: 1.07em;
}
input::placeholder {
    color: var(--muted);
}
.input-with-unit {
    height: 46px;
    border: 1.5px solid var(--border-color);
    border-radius: var(--radius-control);
    background-color: var(--input-bg);
}
.input-with-unit input[type='number'],
.input-with-unit input[type='number']:focus {
    height: 100%;
    border: 0;
    padding: 0 14px;
    font-variant-numeric: tabular-nums;
}
.input-unit {
    color: var(--muted);
    background: transparent;
    padding: 0 14px 0 0;
    font-size: 1em;
    font-weight: 500;
}
.max-oven-temp-group {
    max-width: none;
    margin-top: 14px;
}
/* sweetener type select carries an inline width/border */
#sweetenerType {
    width: 96px !important;
    padding: 0 26px 0 12px !important;
    border: 1.5px solid var(--border-color) !important;
    border-radius: var(--radius-control) !important;
}

/* ---- 5.7 Lock and info buttons, checkboxes ----------------------- */
.lock-btn {
    top: -6px;
    right: -6px;
    padding: 10px;
    color: var(--muted);
    opacity: 1;
}
.lock-btn:hover {
    color: var(--accent-ink);
}
.lock-btn.locked {
    color: var(--accent-ink);
}
.lock-icon {
    width: 15px;
    height: 15px;
}
.lock-icon svg {
    fill: currentColor;
}
.info-icon {
    width: 18px;
    height: 18px;
    color: var(--accent-ink);
}
@media (hover: hover) {
    .info-icon:hover {
        color: var(--primary-hover);
    }
}
.checkbox-label,
.preferment-flour-check {
    gap: 10px;
    margin-bottom: 0;
    min-height: 40px;
    color: var(--card-text);
    font-size: 1.036em;
    font-weight: 500;
}
.checkbox-label input[type='checkbox'],
.preferment-flour-check input[type='checkbox'],
#oldDoughOverrideToggle {
    -webkit-appearance: none;
    appearance: none;
    position: relative;
    flex: none;
    width: 22px;
    height: 22px;
    margin: 0 !important;
    border: 1.5px solid var(--border-color);
    border-radius: 6px;
    background: var(--input-bg);
    cursor: pointer;
    transition:
        background 0.15s,
        border-color 0.15s;
}
.checkbox-label input[type='checkbox']:checked,
.preferment-flour-check input[type='checkbox']:checked,
#oldDoughOverrideToggle:checked {
    background: var(--primary-color);
    border-color: var(--primary-color);
}
.checkbox-label input[type='checkbox']:checked::after,
.preferment-flour-check input[type='checkbox']:checked::after,
#oldDoughOverrideToggle:checked::after {
    content: '';
    position: absolute;
    left: 6.5px;
    top: 2.5px;
    width: 5px;
    height: 10px;
    border: solid var(--on-accent);
    border-width: 0 2.5px 2.5px 0;
    transform: rotate(45deg);
}
.preferment-flour-check input[type='checkbox'] {
    width: 22px;
}
.toggle-label {
    color: var(--muted);
}
.toggle-label.active {
    color: var(--accent-ink);
}

/* ---- 5.8 Preset chips (Advanced) --------------------------------- */
.preset-buttons {
    gap: 6px 5px;
}
.preset-btn {
    min-height: 30px;
    padding: 4px 10px;
    border: 1.5px solid var(--border-color);
    border-radius: 999px;
    background: var(--card-bg);
    color: var(--card-text);
    font-size: 0.929em;
    font-weight: 600;
}
@media (hover: hover) {
    .preset-btn:hover {
        background: var(--tint);
        border-color: var(--primary-color);
        color: var(--card-text);
    }
    .preset-btn.selected:hover {
        background: var(--primary-hover);
        border-color: var(--primary-hover);
        color: var(--on-accent);
    }
}
.preset-btn.selected {
    background: var(--primary-color);
    border-color: var(--primary-color);
    color: var(--on-accent);
}
.preset-btn.preset-custom,
.preset-btn.preset-load {
    border-style: dashed;
    color: var(--accent-ink);
}
.preset-btn.preset-custom.selected {
    border-style: solid;
    color: var(--on-accent);
}
.preset-size-section {
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--border-light);
}

/* ---- 5.9 Flour blend rows ---------------------------------------- */
.blend-row {
    gap: 8px;
    margin-bottom: 8px;
}
.blend-pct-input {
    width: 72px;
    height: 46px;
    padding: 0 8px;
    border: 1.5px solid var(--border-color);
    border-radius: var(--radius-control);
    background: var(--input-bg);
    color: var(--card-text);
    font-size: 1.07em;
    font-variant-numeric: tabular-nums;
}
.blend-pct-wrap {
    gap: 4px;
}
.blend-pct-symbol {
    color: var(--muted);
    opacity: 1;
}
.blend-remove-btn {
    height: 36px;
    color: var(--muted);
    opacity: 1;
}
.blend-remove-btn:hover {
    color: var(--alert-danger-border);
}
.blend-add-btn {
    height: 40px;
    border: 1.5px dashed var(--border-color);
    border-radius: 10px;
    background: none;
    color: var(--accent-ink);
    font-size: 1em;
    font-weight: 600;
}
.blend-add-btn:hover {
    border-color: var(--primary-color);
    background: var(--tint);
}
.blend-info {
    padding: 8px 12px;
    border-radius: 10px;
    background: var(--surface-2);
    color: var(--muted);
    opacity: 1;
}
.old-dough-locked {
    opacity: 0.5;
}
#old-dough-section {
    border: 1px solid var(--border-color);
    border-radius: 12px;
    background: var(--surface-2);
}

/* ---- 5.10 Callouts: full 1px border, no left bar ------------------ */
.alert {
    border-left-width: 1px;
    font-size: 0.964em;
}
.alert-info {
    background: var(--alert-info-bg);
    color: var(--alert-info-text);
}
.alert-warning {
    background: var(--alert-warning-bg);
    color: var(--alert-warning-text);
}
.alert-danger {
    background: var(--alert-danger-bg);
    color: var(--alert-danger-text);
}
.alert-success {
    background: var(--alert-success-bg);
    color: var(--alert-success-text);
}
.alert a,
.warning-links a {
    color: inherit;
    text-decoration: underline;
}
/* other boxes that used to carry a coloured left bar */
.info-text,
.bassinage-info-text,
.preset-description,
.settings-info-box,
.calcs-only-banner,
.instruction-step.step-info,
.changelog-aside {
    padding: 10px 12px;
    border: 1px solid var(--alert-info-border);
    border-radius: var(--radius-callout);
    background: var(--alert-info-bg);
    color: var(--alert-info-text);
    font-size: 0.964em;
    font-style: normal;
    line-height: 1.5;
}
.info-text,
.bassinage-info-text,
.preset-description {
    margin-top: 10px;
}
.instruction-step.step-warning {
    padding: 10px 12px;
    border: 1px solid var(--alert-warning-border);
    border-radius: var(--radius-callout);
    background: var(--alert-warning-bg);
    color: var(--alert-warning-text);
    font-size: 0.964em;
}
.instruction-step.step-info,
.instruction-step.step-warning {
    margin: 10px 0;
}
.instruction-step.step-info .step-title,
.instruction-step.step-warning .step-title {
    color: inherit;
    font-size: 1em;
    font-weight: 700;
}
.instruction-step.step-info .step-tip,
.instruction-step.step-warning .step-tip {
    background: transparent;
    color: inherit;
    padding: 0;
}
.instruction-step.step-info .step-tip::before,
.instruction-step.step-warning .step-tip::before {
    display: none;
}
.advanced-nudge {
    padding: 12px 32px 12px 12px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-callout);
    background: var(--surface-2);
    font-size: 0.964em;
}
.advanced-nudge-cta {
    color: var(--accent-ink);
    font-weight: 600;
}
.water-temp-target-note {
    font-style: normal;
}

/* ---- 5.11 Tips ---------------------------------------------------- */
.step-tip {
    display: block;
    margin-top: 8px;
    padding: 8px 12px;
    border: 0;
    border-radius: var(--radius-callout);
    background: var(--surface-2);
    color: var(--muted);
    font-size: 0.964em;
    font-style: normal;
}
.step-tip:has(> .tip-ic) {
    display: flex;
    gap: 8px;
    align-items: flex-start;
}
/* until the markup carries an icon, draw the bulb in CSS */
.step-tip:not(:has(.tip-ic)) {
    position: relative;
    padding-left: 36px;
}
.step-tip:not(:has(.tip-ic))::before {
    content: '';
    position: absolute;
    left: 12px;
    top: 10px;
    width: 16px;
    height: 16px;
    background: var(--accent-ink);
    -webkit-mask: var(--bulb-mask) center / contain no-repeat;
    mask: var(--bulb-mask) center / contain no-repeat;
}
.instruction-step.step-info .step-tip:not(:has(.tip-ic)),
.instruction-step.step-warning .step-tip:not(:has(.tip-ic)) {
    padding-left: 0;
}
.step-tip a {
    color: var(--accent-ink);
    font-weight: 600;
}

/* ---- 5.12 Result tiles ------------------------------------------- */
.results {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
}
.result-item {
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 12px 8px;
    border-radius: 14px;
    background: var(--primary-color);
    color: var(--on-accent);
    text-align: center;
}
.result-label {
    font-size: 0.929em;
    opacity: 0.92;
    margin-bottom: 0;
}
.result-value {
    font-size: 2em;
    font-weight: 700;
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
}
.result-unit {
    font-size: 0.5em;
    font-weight: 600;
    opacity: 0.9;
}
.result-tsp,
.result-baker-pct {
    font-size: 0.893em;
    font-variant-numeric: tabular-nums;
    opacity: 0.88;
    margin-top: 0;
}
.flour-breakdown,
.water-breakdown {
    background: var(--tint);
    border-radius: 10px;
    color: var(--card-text);
}
.info-toggle,
.details-toggle {
    color: var(--accent-ink);
    font-size: 1em;
    font-weight: 600;
}
.info-toggle:hover,
.details-toggle:hover {
    color: var(--primary-hover);
}
.info-toggle {
    margin-top: 0;
    padding-bottom: 12px;
}
.info-toggle .info-icon {
    width: 17px;
    height: 17px;
}
.details-toggle {
    margin-top: 14px;
    padding-top: 12px;
}
.details-toggle-icon {
    color: var(--muted);
}
.details-summary,
.calc-info-section {
    padding: 12px;
    border-radius: var(--radius-callout);
    background: var(--surface-2);
    font-size: 0.964em;
}
.details-summary .detail-label,
.calc-info-step {
    color: var(--card-text);
}
.details-summary .detail-value {
    font-variant-numeric: tabular-nums;
}

/* ---- 5.13 Share / save / batch buttons ---------------------------- */
.share-section {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin: 16px 0;
}
/* Equal widths while the labels fit on one row; when they don't (large Font
   size, long languages) each button takes its own full-width row instead of
   wrapping its label onto two lines. */
.share-btn,
.action-btn {
    display: inline-flex;
    flex: 1 1 0;
    min-width: min(100%, max-content);
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 46px;
    padding: 0 16px;
    white-space: nowrap;
    border: 1.5px solid var(--border-color);
    border-radius: var(--radius-control);
    background: var(--card-bg);
    color: var(--card-text);
    font-size: 1.07em;
    font-weight: 600;
}
.share-btn:hover,
.action-btn:hover {
    border-color: var(--primary-color);
    background: var(--surface-2);
    color: var(--card-text);
}
.share-btn:active,
.action-btn:active {
    background: var(--tint);
}
.share-btn > .icon,
.action-btn > .icon {
    width: 18px;
    height: 18px;
}
.share-btn-icon,
.action-btn-icon {
    display: inline-flex;
    font-size: 1em;
}
.action-btn.batch-btn {
    flex-basis: 100%;
    border-color: var(--primary-color);
    background: var(--primary-color);
    color: var(--on-accent);
}
.action-btn.batch-btn:hover {
    border-color: var(--primary-hover);
    background: var(--primary-hover);
    color: var(--on-accent);
}
.action-btn.batch-btn .icon {
    color: inherit;
}

/* ---- 5.14 Timeline ------------------------------------------------ */
.timeline-container {
    margin: 16px 0;
    padding: 16px;
    border: 1px solid var(--border-color);
    border-radius: 14px;
    background: var(--card-bg);
    box-shadow: none;
}
.timeline-header {
    flex-direction: row;
    /* the Total pill drops below the title when both don't fit (large Font
       size, long languages) instead of squeezing the title onto two lines */
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 8px;
    margin-bottom: 12px;
    padding-bottom: 0;
    border-bottom: 0;
}
.timeline-header:hover {
    opacity: 1;
}
.timeline-header-left {
    gap: 6px;
}
.timeline-toggle-icon {
    display: inline-flex;
    color: var(--muted);
    font-size: 1em;
}
.timeline-toggle-icon .icon {
    width: 18px;
    height: 18px;
    color: var(--muted);
}
.timeline-title {
    color: var(--card-heading);
    font-size: 1.143em;
    font-weight: 700;
}
.timeline-total {
    align-self: center;
    padding: 3px 10px;
    border-radius: 999px;
    background: var(--tint);
    color: var(--accent-ink);
    font-size: 0.929em;
    font-weight: 600;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}
.timeline-track {
    gap: 0;
}
.timeline-event {
    display: grid;
    grid-template-columns: 40px 1fr;
    column-gap: 12px;
    align-items: start;
    padding: 6px 0;
}
.timeline-marker {
    width: 40px;
    height: 40px;
    border: 2px solid var(--primary-color);
    background: var(--card-bg);
    color: var(--accent-ink);
    font-size: 1em;
    box-shadow: none;
}
.timeline-icon {
    display: inline-flex;
    filter: none;
}
.timeline-icon .icon {
    width: 19px;
    height: 19px;
}
.timeline-event:first-child .timeline-marker {
    background: var(--primary-color);
    color: var(--on-accent);
}
.timeline-event:first-child .timeline-marker .icon {
    color: inherit;
}
.timeline-content {
    display: grid;
    grid-template-columns: 1fr auto;
    column-gap: 12px;
    align-items: center;
    min-height: 40px;
    margin: 0;
    padding: 0;
}
.timeline-label {
    margin: 0;
    color: var(--card-heading);
    font-size: 1.07em;
    font-weight: 600;
}
.timeline-time {
    color: var(--accent-ink);
    font-size: 0.929em;
    font-weight: 600;
    line-height: 1.25;
    opacity: 1;
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.timeline-line {
    left: 19px;
    top: 46px;
    bottom: -6px;
    width: 2px;
    border-radius: 0;
    background: var(--border-color);
}
@media (min-width: 768px) {
    .timeline-event {
        display: flex;
        flex-direction: column;
        align-items: center;
        padding: 0;
    }
    .timeline-marker {
        width: 40px;
        height: 40px;
        font-size: 1em;
    }
    .timeline-content {
        display: block;
        min-height: 0;
        margin-top: 10px;
        text-align: center;
    }
    .timeline-label {
        font-size: 0.964em;
    }
    .timeline-time {
        margin-top: 2px;
        font-size: 0.857em;
        text-align: center;
    }
    .timeline-line {
        left: auto;
        right: -50%;
        top: 19px;
        bottom: auto;
        width: 100%;
        height: 2px;
        background: var(--border-color);
    }
}
@media (max-width: 600px) {
    .timeline-container {
        padding: 16px;
    }
    .timeline-header {
        flex-direction: row;
    }
    .timeline-marker {
        width: 40px;
        height: 40px;
        font-size: 1em;
    }
    .timeline-content {
        margin-left: 0;
        padding-top: 0;
    }
    .timeline-label {
        font-size: 1.07em;
    }
    .timeline-time {
        font-size: 0.929em;
    }
    .timeline-line {
        left: 19px;
        top: 46px;
    }
}

/* ---- 5.15 Phases, steps, numbers ---------------------------------- */
.instruction-phase {
    margin-bottom: 14px;
}
.phase-header {
    gap: 9px;
    margin: 10px 0 4px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border-color);
    color: var(--accent-ink);
    font-size: 1.07em;
    font-weight: 700;
    letter-spacing: 0;
    text-transform: none;
}
.phase-icon {
    display: inline-flex;
    font-size: 1em;
}
.phase-icon .icon {
    width: 19px;
    height: 19px;
}
.instruction-step {
    padding: 12px 0;
    border-bottom: 1px solid var(--border-light);
    color: var(--step-text);
    font-size: 1.036em;
    line-height: 1.55;
}
.step-number {
    width: 28px;
    height: 28px;
    background: var(--primary-color);
    color: var(--on-accent);
    font-size: 0.929em;
    font-variant-numeric: tabular-nums;
}
.step-title {
    color: var(--step-title);
    font-weight: 700;
}

/* ---- 5.16 Floating quick-reference bar ---------------------------- */
.floating-summary-bar {
    /* the 7-tile bar must fit a phone: scale with Font size, but cap at 105% */
    --qr-scale: min(var(--font-scale, 1), 1.05);
    background: var(--dock-bg);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    border-top: 1px solid var(--border-color);
    box-shadow: none;
    padding: 8px 0 10px;
}
.floating-summary-title {
    margin-bottom: 6px;
    color: var(--muted);
    text-align: center;
    text-transform: uppercase;
    font-size: calc(10.5px * var(--qr-scale));
    letter-spacing: 0.08em;
    opacity: 1;
}
.floating-summary-inner {
    gap: 6px;
}
.floating-summary-item {
    padding: 6px 4px;
    border-radius: 8px;
    background: var(--tint);
    color: var(--accent-ink);
    line-height: 1.15;
}
.floating-summary-item:last-child {
    background: var(--primary-color);
    color: var(--on-accent);
}
.floating-summary-label {
    color: var(--muted);
    font-size: calc(11px * var(--qr-scale));
    letter-spacing: 0;
    opacity: 1;
    text-transform: none;
}
.floating-summary-item:last-child .floating-summary-label {
    color: inherit;
    opacity: 0.88;
}
.floating-summary-value {
    font-size: calc(15px * var(--qr-scale));
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.floating-summary-unit {
    font-size: calc(10.5px * var(--qr-scale));
    opacity: 0.8;
}
.floating-summary-bar.calculating .floating-summary-item {
    filter: none;
}
@media (max-width: 600px) {
    .floating-summary-inner {
        gap: 4px;
    }
}

/* ---- 5.17 Modals and shared dialog parts -------------------------- */
.modal-overlay {
    background: rgba(0, 0, 0, 0.55);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
}
.modal-dialog {
    border-radius: var(--radius-card);
    background: var(--card-bg);
}
.modal-header {
    border-bottom: 1px solid var(--border-light);
}
.modal-title {
    display: flex;
    align-items: center;
    gap: 9px;
    font-size: 1.286em;
}
.modal-title .icon {
    width: 20px;
    height: 20px;
}
.modal-close-btn {
    display: inline-grid;
    place-items: center;
    width: 44px;
    height: 44px;
    margin: -10px -12px -10px 0;
    color: var(--muted);
}
.modal-close-btn:hover {
    color: var(--card-text);
}
.modal-btn {
    min-height: 46px;
    padding: 0 20px;
    border: 1.5px solid transparent;
    border-radius: var(--radius-control);
    font-size: 1em;
}
.modal-btn-primary {
    border-color: var(--primary-color);
    background: var(--primary-color);
    color: var(--on-accent);
}
.modal-btn-primary:hover {
    background: var(--primary-hover);
    border-color: var(--primary-hover);
    box-shadow: none;
    transform: none;
    opacity: 1;
}
.modal-btn-secondary {
    border-color: var(--border-color);
    background: var(--card-bg);
    color: var(--card-text);
}
.modal-btn-secondary:hover {
    background: var(--surface-2);
}
.share-recipe-summary {
    border-radius: var(--radius-callout);
    background: var(--surface-2);
}
.share-label {
    color: var(--label-color);
}
.share-custom-name-input,
.share-link-input {
    height: 46px;
    padding: 0 14px;
    border: 1.5px solid var(--border-color);
    border-radius: var(--radius-control);
}
.share-custom-name-hint {
    color: var(--muted);
}
.share-copy-btn {
    height: 46px;
    border-radius: var(--radius-control);
    background: var(--primary-color);
    color: var(--on-accent);
}
.share-copy-btn:hover {
    background: var(--primary-hover);
    opacity: 1;
}
.share-option-btn {
    border: 1.5px solid var(--border-color);
    border-radius: var(--radius-control);
    background: var(--card-bg);
}
.share-option-btn:hover {
    border-color: var(--primary-color);
    background: var(--tint);
}
.share-option-icon {
    display: inline-flex;
    font-size: 1em;
}
.share-option-icon .icon {
    width: 22px;
    height: 22px;
}

/* ---- 5.18 Calc error overlay, toasts, term hints ------------------ */
.calculation-error .error-content {
    border-radius: var(--radius-card);
    background: var(--card-bg);
}
.calculation-error .error-icon {
    display: inline-grid;
    place-items: center;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--alert-danger-bg);
    font-size: 1em;
}
.calculation-error .error-icon .icon {
    width: 28px;
    height: 28px;
    color: var(--alert-danger-border);
}
.calculation-error .error-title {
    color: var(--alert-danger-text);
}
.calculation-error .error-message {
    color: var(--card-text);
}
.calculation-error .error-dismiss {
    min-height: 46px;
    padding: 0 24px;
    border-radius: var(--radius-control);
    background: var(--primary-color);
    color: var(--on-accent);
    font-weight: 600;
}
.share-bake-toast {
    border: 1px solid var(--border-color);
    border-radius: 14px;
    background: var(--card-bg);
    color: var(--card-text);
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.25);
}
.share-bake-toast-text {
    color: var(--card-text);
}
.share-bake-toast-close {
    color: var(--muted);
}
.share-bake-toast-btn {
    border: 1.5px solid var(--primary-color);
    border-radius: var(--radius-control);
    background: var(--primary-color);
    color: var(--on-accent);
}
.share-bake-toast-btn:hover {
    border-color: var(--primary-hover);
    background: var(--primary-hover);
}
.share-bake-toast-btn-secondary {
    border-color: var(--border-color);
    background: transparent;
    color: var(--accent-ink);
}
.share-bake-toast-btn-secondary:hover {
    border-color: var(--primary-color);
    background: var(--tint);
    color: var(--accent-ink);
}
.term-hint {
    text-decoration-color: var(--accent-ink);
}
.term-tooltip {
    border: 1px solid var(--border-color);
    border-radius: 12px;
    background: var(--card-bg);
    color: var(--card-text);
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.22);
}
.term-tooltip-link {
    color: var(--accent-ink);
}

/* ---- 5.19 Wide (>= 768px): same column, tighter rows -------------- */
@media (min-width: 768px) {
    .time-options {
        grid-template-columns: repeat(3, 1fr);
    }
    .results {
        grid-template-columns: repeat(4, 1fr);
    }
    .share-section {
        max-width: 420px;
        margin-inline: auto;
    }
    .btn-block,
    .calculation-error .error-dismiss {
        max-width: 420px;
        margin-inline: auto;
    }
}
/* WP-C:END */

/* ------------------------------------------------------------------ */
/* 6. Web calculator additions (work package W owns this section)      */
/* ------------------------------------------------------------------ */
/* WP-W:BEGIN */
/* Brand bar (web calculator): centred logo + wordmark, language left, settings right */
.brand-bar {
    display: grid;
    /* sides never narrower than their button, so the language pill can't
       slide under the logo; the wordmark wraps instead */
    grid-template-columns: minmax(max-content, 1fr) minmax(0, auto) minmax(max-content, 1fr);
    align-items: center;
    gap: 8px;
    padding-top: 12px;
    margin-bottom: 16px;
}
.brand-bar .brand {
    margin: 0;
    grid-column: 2;
}
.brand-side {
    display: flex;
    align-items: center;
    min-width: 0;
}
.brand-side-start {
    grid-column: 1;
    justify-content: flex-start;
}
.brand-side-end {
    grid-column: 3;
    justify-content: flex-end;
}
.brand-bar .brand-logo {
    object-fit: cover;
}
.brand-bar .brand-sub {
    font-size: 0.95em;
    overflow-wrap: anywhere;
}
.brand-bar .settings-btn {
    width: 44px;
    height: 44px;
    border: 1.5px solid color-mix(in srgb, var(--header-text) 35%, transparent);
    background: color-mix(in srgb, var(--header-text) 14%, transparent);
    color: var(--header-text);
}
.brand-bar .settings-btn .icon,
.brand-bar .settings-btn .settings-icon {
    width: 21px;
    height: 21px;
    color: inherit;
}
.brand-bar .lang-switcher {
    color: var(--header-text);
}
/* Language pill: same height, outline and tint as the settings button so
   the two sides of the brand bar balance. */
.brand-bar .lang-current {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 44px;
    box-sizing: border-box;
    padding: 0 14px 0 12px;
    border: 1.5px solid color-mix(in srgb, var(--header-text) 35%, transparent);
    border-radius: 999px;
    background: color-mix(in srgb, var(--header-text) 14%, transparent);
    color: var(--header-text);
    font-size: 1.05em;
    font-weight: 700;
    letter-spacing: 0.02em;
    opacity: 1;
    transition: background-color 0.15s;
}
.brand-bar .lang-current::after {
    display: none;
}
.brand-bar .lang-current:hover,
.brand-bar .lang-switcher[open] .lang-current {
    background: color-mix(in srgb, var(--header-text) 24%, transparent);
}
.brand-bar .lang-current .lang-ic {
    width: 18px;
    height: 18px;
    color: inherit;
    flex-shrink: 0;
}
@media (max-width: 600px) {
    .brand-bar .lang-current {
        gap: 4px;
        padding: 0 10px 0 8px;
        font-size: 0.95em;
    }
    .brand-bar .lang-current .lang-ic {
        width: 16px;
        height: 16px;
    }
}
@media (max-width: 374px) {
    .brand-bar .lang-current {
        padding: 0 12px;
    }
    .brand-bar .lang-current .lang-ic {
        display: none;
    }
}
.brand-bar .settings-btn {
    transition: background-color 0.15s;
}
.brand-bar .settings-btn:hover {
    background: color-mix(in srgb, var(--header-text) 24%, transparent);
}
@media (max-width: 359px) {
    .brand-bar {
        grid-template-columns: 1fr 1fr;
    }
    .brand-bar .brand {
        grid-column: 1 / -1;
        grid-row: 1;
        justify-content: center;
    }
    .brand-side-start {
        grid-column: 1;
        grid-row: 2;
    }
    .brand-side-end {
        grid-column: 2;
        grid-row: 2;
    }
}

/* Page intro under the brand. The brand banner already names the app, so
   the H1 is visually hidden (kept for SEO and screen readers) and the
   description sits on the page background like the mode hint, without a
   card, at every width. */
.page-header {
    background: none;
    box-shadow: none;
    border: 0;
    border-radius: 0;
    padding: 0 4px;
    margin: 0 auto 18px;
    max-width: 680px;
    text-align: center;
}
.page-header h1.card-title {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}
.page-header h2 {
    font-size: 1.15em;
    font-weight: 700;
    color: var(--header-text);
}
.page-header p {
    color: color-mix(in srgb, var(--header-text) 88%, transparent);
    font-size: 0.95em;
    line-height: 1.55;
}
.page-header p a,
.page-header p a:hover {
    color: var(--header-text);
    text-decoration: underline;
    text-underline-offset: 2px;
}
.intro-toggle-btn {
    border: 0;
    border-radius: 0;
    padding: 6px 0 2px;
    margin-top: 6px;
    color: var(--header-text);
    opacity: 0.85;
    font-size: 0.9em;
    font-weight: 600;
}
.intro-toggle-btn:hover {
    color: var(--header-text);
    border: 0;
    text-decoration: underline;
}
@media (max-width: 600px) {
    .page-header p {
        font-size: 0.9em;
        line-height: 1.5;
    }
}

/* Mode switch row: centred under the brand */
.mode-toggle-container {
    margin: 0 0 14px;
}
.mode-toggle-wrapper {
    align-items: center;
    max-width: 100%;
}
.mode-toggle-wrapper .mode-hint {
    color: var(--header-text);
    opacity: 0.85;
    font-size: 0.86em;
    margin-top: 6px;
    text-align: center;
}
@media (max-width: 374px) {
    .mode-toggle-wrapper .mode-hint {
        display: block;
    }
}

/* Style slider hint: arrows are the only navigation (no overlay buttons over the cards) */
.style-scroller .scroll-arrow {
    display: none;
}
.style-scroller {
    margin-bottom: 0;
}
.style-grid {
    margin-inline: -16px;
    padding: 4px 16px 8px;
    scroll-padding-inline: 16px;
    scroll-snap-type: x mandatory;
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 36px), transparent);
    mask-image: linear-gradient(90deg, #000 calc(100% - 36px), transparent);
}
.style-grid .style-card {
    scroll-snap-align: start;
}
.style-grid.scrolled {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 28px, #000 calc(100% - 36px), transparent);
    mask-image: linear-gradient(90deg, transparent, #000 28px, #000 calc(100% - 36px), transparent);
}
.style-grid.at-end {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 28px);
    mask-image: linear-gradient(90deg, transparent, #000 28px);
}
.style-grid.no-overflow {
    -webkit-mask-image: none;
    mask-image: none;
}
.style-hint .hint-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 32px;
    margin: 0 -10px;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}
.style-hint .hint-btn:disabled {
    cursor: default;
}
.style-hint .hint-arrow {
    color: var(--muted);
}

/* Labels with icons */
.form-group > label,
.form-group > label.label-with-info {
    display: flex;
    align-items: center;
}
.form-group > label .label-ic {
    flex: none;
}
.group-label {
    display: flex;
    align-items: center;
    margin-bottom: 6px;
    font-weight: 600;
    color: var(--label-color);
}
.sub-label {
    font-size: 0.85em;
    color: var(--muted);
}
.field-note {
    margin-top: 8px;
    font-size: 0.85em;
    color: var(--muted);
}
.sweetener-row {
    display: flex;
    gap: 8px;
}
.sweetener-select {
    width: 110px;
    flex: none;
}

/* Stepper glyphs are line icons on the accent button */
.stepper-btn .stepper-ic,
.font-size-btn .stepper-ic {
    width: 18px;
    height: 18px;
    color: inherit;
}

/* Callouts with an icon: body wraps the text so the icon stays a flex sibling */
.alert > .alert-body {
    flex: 1;
    min-width: 0;
}

/* Blend rows */
.blend-add-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.blend-remove-btn .icon {
    width: 16px;
    height: 16px;
    color: inherit;
}

/* Results card bits */
.phase-icon .phase-ic {
    width: 19px;
    height: 19px;
    vertical-align: -4px;
    margin-right: 4px;
}
.info-toggle .btn-ic {
    margin-right: 6px;
    vertical-align: -4px;
}
.details-toggle-icon {
    display: inline-flex;
    font-size: inherit;
}
.details-toggle-icon .icon {
    width: 16px;
    height: 16px;
    color: inherit;
}
.kitchen-scale-link {
    margin: 14px 0 12px;
    text-align: center;
}
.kitchen-scale-link .info-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--accent-ink);
    font-size: 0.95em;
    font-weight: 600;
    text-decoration: none;
}
.kitchen-scale-link .info-link:hover {
    text-decoration: underline;
}

/* Share button: the one primary action here, full width (capped on wide screens) */
.share-section .share-btn {
    display: flex;
    width: 100%;
    align-items: center;
    justify-content: center;
    gap: 8px;
}
.share-btn-icon .icon {
    width: 18px;
    height: 18px;
    color: inherit;
}

/* Affiliate ratings: star icons */
.affiliate-product-rating .stars {
    display: inline-flex;
    gap: 1px;
    vertical-align: middle;
}
.affiliate-product-rating .star-ic {
    width: 13px;
    height: 13px;
}
.affiliate-product-rating .star-empty {
    color: var(--muted);
    opacity: 0.6;
}

/* Modals: icon titles, x close buttons */
.modal-title {
    display: flex;
    align-items: center;
    gap: 9px;
}
.modal-close-btn .icon,
.app-promo-close .icon,
.advanced-nudge-dismiss .icon,
.summary-card-close .icon,
.share-bake-toast-close .icon {
    width: 20px;
    height: 20px;
    color: inherit;
    vertical-align: middle;
}

/* Settings modal rows: icon + label */
.settings-label {
    display: inline-flex;
    align-items: center;
    gap: 10px;
}
.settings-label .row-ic {
    width: 20px;
    height: 20px;
}

/* Share modal grid: icons instead of emoji */
.share-option-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.share-option-icon .icon {
    width: 22px;
    height: 22px;
}

/* Calculation error overlay icon */
.error-icon .error-ic {
    width: 40px;
    height: 40px;
    color: var(--alert-warning-border);
}

/* Dev badge icon */
.dev-env-icon .icon {
    width: 16px;
    height: 16px;
    color: inherit;
}
/* Wide (>= 768px): the phone layout at about twice the width (guidelines section 5) */
@media (min-width: 768px) {
    .time-options {
        grid-template-columns: repeat(3, 1fr);
    }
    .results {
        grid-template-columns: repeat(4, 1fr);
    }
    .share-section .share-btn {
        max-width: 420px;
        margin-inline: auto;
    }
}
/* WP-W:END */

/* ------------------------------------------------------------------ */
/* 7. App additions shared with web markup (work packages M1/M2)       */
/* ------------------------------------------------------------------ */
/* WP-M:BEGIN */
/* WP-M:END */

/* ------------------------------------------------------------------ */
/* 8. Lead review fixes (post-merge review, 2026-10-16)                */
/* ------------------------------------------------------------------ */
/* Grid columns must be allowed to shrink below their content (long flour
   names, German labels, font scale 1.4 pushed the page wider than the phone). */
.form-grid-2col {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}
@media (max-width: 600px) {
    .form-grid-2col {
        grid-template-columns: minmax(0, 1fr);
    }
}
.form-group,
.form-group-lockable {
    min-width: 0;
}
select {
    max-width: 100%;
    min-width: 0;
}
.form-grid-2col > .alert,
.form-grid-2col > .info-text {
    grid-column: 1 / -1;
}

/* The base `input[type='number']` rule outranked `.stepper-value`. */
.stepper .stepper-value {
    font-size: 1.214em;
    font-weight: 600;
}

/* Plain labels flow inline so "Altitude (feet)" keeps its space before "(".
   Labels with an info button or lock stay flex. */
.form-group > label:not(.label-with-info):not(:has(.info-icon, .lock-btn)) {
    display: block;
}

/* Callouts without an icon in the markup (text injected by JS, translated HTML,
   blog markdown) draw the same icon with a CSS mask, so every callout matches. */
.alert:not(:has(> .alert-ic)) {
    position: relative;
    padding-left: 38px;
}
.alert:not(:has(> .alert-ic))::before {
    content: '';
    position: absolute;
    left: 12px;
    top: 11px;
    width: 18px;
    height: 18px;
    background: var(--alert-info-border);
    -webkit-mask: var(--alert-mask) center / contain no-repeat;
    mask: var(--alert-mask) center / contain no-repeat;
    --alert-mask: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%20%3E%20%3Ccircle%20cx=%2212%22%20cy=%2212%22%20r=%2210%22%20/%3E%20%3Cpath%20d=%22M12%2016v-4%22%20/%3E%20%3Cpath%20d=%22M12%208h.01%22%20/%3E%20%3C/svg%3E');
}
.alert-warning:not(:has(> .alert-ic))::before {
    background: var(--alert-warning-border);
    --alert-mask: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%20%3E%20%3Cpath%20d=%22m21.73%2018-8-14a2%202%200%200%200-3.48%200l-8%2014A2%202%200%200%200%204%2021h16a2%202%200%200%200%201.73-3%22%20/%3E%20%3Cpath%20d=%22M12%209v4%22%20/%3E%20%3Cpath%20d=%22M12%2017h.01%22%20/%3E%20%3C/svg%3E');
}
.alert-danger:not(:has(> .alert-ic))::before {
    background: var(--alert-danger-border);
    --alert-mask: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%20%3E%20%3Ccircle%20cx=%2212%22%20cy=%2212%22%20r=%2210%22%20/%3E%20%3Cline%20x1=%2212%22%20x2=%2212%22%20y1=%228%22%20y2=%2212%22%20/%3E%20%3Cline%20x1=%2212%22%20x2=%2212.01%22%20y1=%2216%22%20y2=%2216%22%20/%3E%20%3C/svg%3E');
}
.alert-success:not(:has(> .alert-ic))::before {
    background: var(--alert-success-border);
    --alert-mask: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%20%3E%20%3Ccircle%20cx=%2212%22%20cy=%2212%22%20r=%2210%22%20/%3E%20%3Cpath%20d=%22m9%2012%202%202%204-4%22%20/%3E%20%3C/svg%3E');
}

/* Step explainers ("What is autolyse?") get the info icon like other callouts */
.instruction-step.step-info .step-title::before {
    content: '';
    display: inline-block;
    width: 1.15em;
    height: 1.15em;
    margin-right: 0.35em;
    vertical-align: -0.22em;
    background: var(--alert-info-border);
    -webkit-mask: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%20%3E%20%3Ccircle%20cx=%2212%22%20cy=%2212%22%20r=%2210%22%20/%3E%20%3Cpath%20d=%22M12%2016v-4%22%20/%3E%20%3Cpath%20d=%22M12%208h.01%22%20/%3E%20%3C/svg%3E')
        center / contain no-repeat;
    mask: url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%20%3E%20%3Ccircle%20cx=%2212%22%20cy=%2212%22%20r=%2210%22%20/%3E%20%3Cpath%20d=%22M12%2016v-4%22%20/%3E%20%3Cpath%20d=%22M12%208h.01%22%20/%3E%20%3C/svg%3E')
        center / contain no-repeat;
}

/* A field whose warning is showing takes the full row on wide layouts, so
   the warning doesn't leave a hole beside it. The control itself keeps its
   column width (it used to double, e.g. Diastatic malt going 0 -> 0.1%). */
.form-grid-2col > .form-group:has(> .alert:not(.hidden)) {
    grid-column: 1 / -1;
}
@media (min-width: 601px) {
    .form-grid-2col > .form-group:has(> .alert:not(.hidden)) > :is(.stepper, select) {
        max-width: calc((100% - 14px) / 2);
    }
}

/* Timeline time ("Starts in 15m") reads on one line when it fits and wraps at
   spaces when it does not (longer translations); it never widens its step, so
   the track stays inside its container. */
.timeline-time {
    white-space: normal;
    overflow-wrap: normal;
    text-wrap: balance;
    min-width: 0;
}
.timeline-event,
.timeline-content,
.timeline-label {
    min-width: 0;
}
.timeline-content {
    grid-template-columns: minmax(min-content, 1fr) minmax(0, max-content);
}
.timeline-time {
    max-width: 11em;
    margin-left: auto;
}
@media (min-width: 768px) {
    .timeline-event {
        padding: 0 2px;
    }
    .timeline-content {
        display: block;
        max-width: 100%;
    }
    .timeline-time {
        max-width: 100%;
        margin-left: 0;
    }
}
/* Result tiles at large font scales: the number never splits, the unit stays
   whole, and the unit drops under the number instead of widening the tile
   (French "grammes" at 140% font scale overflowed the page). */
.result-value {
    max-width: 100%;
    white-space: normal;
    overflow-wrap: normal;
}
.result-value > span:first-child {
    white-space: nowrap;
}
.result-value .result-unit {
    display: inline-block;
    white-space: nowrap;
}

/* ------------------------------------------------------------------ */
/* 9. Accessibility (pl-5b7f.1 a11y pass, 2026-10-16)                  */
/* ------------------------------------------------------------------ */
/* Rules here are guarded by tests/unit a11y-contrast + tests/e2e/a11y.
   Many selectors start with :root so they also outrank mobile.css,
   which loads after this file in the app. */

/* Screen-reader-only text (visually hidden, still read and focusable). */
.sr-only {
    position: absolute !important;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* 9.1 Form control outlines: >= 3:1 against the card (WCAG 1.4.11).
   An unchecked checkbox drawn in --border-color (1.3:1) was close to
   invisible. Dividers and card edges keep --border-color. */
:root select,
:root .stepper,
:root .input-with-unit,
:root input[type='number']:where(:not(.stepper-value, .blend-pct-input)),
:root .blend-pct-input,
:root .share-custom-name-input,
:root .share-link-input,
:root .settings-select,
:root .recipe-name-input,
:root .feedback-textarea,
:root .checkbox-label input[type='checkbox'],
:root .preferment-flour-check input[type='checkbox'],
:root #oldDoughOverrideToggle {
    border-color: var(--control-border);
}
:root #sweetenerType {
    border-color: var(--control-border) !important;
}
:root :is(.checkbox-label, .preferment-flour-check) input[type='checkbox']:checked,
:root #oldDoughOverrideToggle:checked {
    border-color: var(--primary-color);
}

/* Switches: the "off" track was --border-color (1.3:1, the switch nearly
   vanished). The input itself is visually hidden, so the ring goes on
   the track. */
:root .settings-toggle input:not(:checked) + .toggle-track {
    background-color: var(--control-border);
}
:root .settings-toggle input:focus-visible + .toggle-track {
    outline: 2px solid var(--accent-ink);
    outline-offset: 2px;
}

/* 9.2 Text on the page gradient: full --header-text, no fade. The mode
   switch track is an outline only, so the inactive label sits on the
   gradient itself (white on a white-tinted track fell to ~3.5:1). */
.mode-toggle {
    background: transparent;
    border-color: color-mix(in srgb, var(--header-text) 45%, transparent);
}
.mode-hint,
.mode-toggle-wrapper .mode-hint {
    color: var(--header-text);
    opacity: 1;
}
.brand-sub {
    opacity: 1;
}

/* 9.3 Quiet text that used opacity on top of an already quiet colour. */
:root .water-temp-target-note,
:root .warning-learn-more,
:root .schedule-phases-title,
:root .schedule-phase-label {
    opacity: 1;
}
:root .affiliate-label {
    color: var(--muted);
    opacity: 1;
}
:root .form-group > a[href$='pizza-tools/#ovens'] {
    color: var(--muted) !important;
    opacity: 1 !important;
}
:root .step-timer-display .timer-label,
:root .step-timer-display.adjustable .timer-label {
    opacity: 1;
}
:root .changelog-entry h4,
:root .footer-link,
:root .affiliate-disclosure,
:root .footer-version {
    opacity: 1;
}
:root .pro-active-badge {
    background: var(--alert-success-bg);
    color: var(--alert-success-text);
    border: 1px solid var(--alert-success-border);
}

/* 9.4 Keyboard focus. One ring everywhere: 2px --accent-ink, 2px offset.
   Legacy `:focus { outline: none }` rules on selects and inputs hid it. */
:root
    :is(
        select,
        input,
        textarea,
        button,
        a,
        summary,
        [role='radio'],
        [role='button'],
        [role='switch'],
        [tabindex]
    ):focus-visible {
    outline: 2px solid var(--accent-ink);
    outline-offset: 2px;
}
/* The stepper's number field has no room for an outside ring between the
   buttons: ring the whole stepper instead. Stepper buttons are solid
   accent, so their ring sits inside in --on-accent (not clipped). */
:root .stepper .stepper-value:focus-visible {
    outline: none;
}
:root .input-with-unit input:focus-visible {
    outline: none;
}
:root .stepper:has(.stepper-value:focus-visible),
:root .input-with-unit:has(input:focus-visible) {
    outline: 2px solid var(--accent-ink);
    outline-offset: 2px;
}
:root .stepper .stepper-btn:focus-visible {
    outline: 2px solid var(--on-accent);
    outline-offset: -5px;
}
/* Solid accent fills (primary buttons, selected chips, Total tile): the
   ring sits outside on the card, which passes; nothing to change.
   Elements sitting on the page gradient ring in --header-text. */
:root :is(.brand-bar, .brand, .app-footer, .mode-toggle-container, .mode-toggle-wrapper) :focus-visible {
    outline-color: var(--header-text);
}
:root .app-promo-banner :focus-visible {
    outline-color: currentColor;
}
/* Style cards sit in a horizontal scroller that clips an outside ring,
   and the selected card already has an accent border: ring inside it. */
:root .style-card:focus-visible {
    outline-offset: -6px;
}

/* 9.5 Touch targets: >= 44px hit area without changing the look. The
   chip keeps its 30px pill; an invisible pseudo-element grows the hit
   area vertically (rows of chips have a 6px gap, so it is split). */
:root
    :is(
        .preset-btn,
        .info-icon,
        .mode-btn,
        .hint-btn,
        .intro-toggle-btn,
        .details-toggle,
        .info-toggle,
        .footer-link,
        .affiliate-browse-link,
        .app-promo-link,
        .warning-learn-more,
        .form-group > a[href$='pizza-tools/#ovens'],
        .lang-current
    ) {
    position: relative;
}
:root
    :is(
        .preset-btn,
        .info-icon,
        .lock-btn,
        .mode-btn,
        .hint-btn,
        .app-promo-close,
        .intro-toggle-btn,
        .details-toggle,
        .info-toggle,
        .footer-link,
        .affiliate-browse-link,
        .app-promo-link,
        .warning-learn-more,
        .form-group > a[href$='pizza-tools/#ovens']
    )::after,
:root .lang-current::before {
    content: '';
    position: absolute;
}
:root .preset-btn::after {
    inset: -7px -3px;
}
:root .info-icon::after {
    inset: -11px -13px;
}
:root .lock-btn::after {
    inset: -5px -5px -2px;
}
:root .app-promo-close::after {
    inset: -8px -4px;
}
:root :is(.mode-btn, .details-toggle, .info-toggle)::after {
    inset: -7px 0;
}
:root .hint-btn::after {
    inset: -6px 0;
}
:root .lang-current::before {
    inset: -6px -1px;
}
:root .intro-toggle-btn::after {
    inset: -11px -4px;
}
:root .footer-link::after {
    inset: -6px 0;
}
/* small standalone text links: >= 24px (WCAG 2.5.8) without touching
   the control above them */
:root :is(.affiliate-browse-link, .warning-learn-more)::after {
    inset: -6px 0;
}
:root .app-promo-link::after {
    inset: -12px 0;
}
:root .form-group > a[href$='pizza-tools/#ovens']::after {
    inset: 0 0 -10px;
}
/* checkbox rows: the whole label is the target */
:root :is(.checkbox-label, .preferment-flour-check) {
    min-height: 44px;
}

/* 9.6 Motion: the global rule above shortens transitions; also stop
   infinite loops (pulsing timers, spinners) and smooth scrolling. */
@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto !important;
    }
    *,
    *::before,
    *::after {
        animation-iteration-count: 1 !important;
        scroll-behavior: auto !important;
    }
}

/* 9.7 Windows High Contrast / forced colours: keep selected states
   visible (they are drawn with background fills). */
@media (forced-colors: active) {
    .style-card[aria-checked='true'],
    .time-option[aria-checked='true'],
    .preset-btn.selected,
    .mode-btn.active {
        outline: 3px solid Highlight;
        outline-offset: -3px;
    }
}

/* 9.8 Reflow (WCAG 1.4.10): at 320px wide with font scale 1.4 or long
   German labels nothing may push the page sideways. */
@media (max-width: 400px) {
    :root .timeline-header {
        flex-wrap: wrap;
        row-gap: 4px;
    }
    :root .timeline-total {
        white-space: normal;
        min-width: 0;
    }
}
:root .nav-item {
    min-width: 0;
}
:root .nav-label {
    max-width: 100%;
    /* wrap only at spaces: never split a word (Rechn/er) */
    overflow-wrap: normal;
    word-break: keep-all;
    hyphens: manual;
    text-align: center;
    line-height: 1.15;
}
/* long single German words in titles (Teigzusammensetzung) */
:root .card-title > span {
    min-width: 0;
    overflow-wrap: anywhere;
    hyphens: auto;
}

/* ------------------------------------------------------------------ */
/* 10. Polish (pl-5b7f.1 WP-polish, 2026-10-16)                        */
/* ------------------------------------------------------------------ */

/* 10.1 Select chevron: a --muted line chevron (Lucide chevron-down).
   A background image cannot read a CSS variable, so each theme carries
   the chevron with its own --muted hex in --select-chevron. */
:root {
    --select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2366657b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
[data-theme='warm'] {
    --select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2373645a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
[data-theme='dark'] {
    --select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2393a0ad' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
[data-theme='cool'] {
    --select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235a6c74' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
[data-theme='light'] {
    --select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23676a7c' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
:root select,
:root .settings-select {
    background-image: var(--select-chevron);
    background-repeat: no-repeat;
    background-position: right 12px center;
    background-size: 18px 18px;
    padding-right: 38px;
}
:root .settings-select {
    height: 44px;
    min-width: 120px;
    max-width: 100%;
    padding-left: 14px;
    border-width: 1.5px;
    border-radius: var(--radius-control);
    background-color: var(--input-bg);
    font-size: 1em;
}
:root #sweetenerType {
    padding-right: 34px !important;
    background-position: right 9px center;
}

/* 10.2 Lock buttons: Lucide line lock / lock-open in --muted, the locked
   state in --accent-ink. The .locked class and E2E hooks are unchanged. */
.lock-icon {
    width: 18px;
    height: 18px;
}
.lock-icon svg {
    width: 100%;
    height: 100%;
    fill: none;
    color: inherit;
    stroke-width: 2;
}

/* 10.3 Settings steppers (font size, wastage, yeast adjustment): the same
   solid-accent stepper as the calculator, as one bordered group. */
:root .font-size-control,
:root .wastage-control {
    gap: 0;
    height: 44px;
    border: 1.5px solid var(--control-border);
    border-radius: var(--radius-control);
    background: var(--input-bg);
    overflow: hidden;
    flex: none;
}
:root .font-size-btn {
    width: 44px;
    height: auto;
    align-self: stretch;
    border: 0;
    border-radius: 0;
    background: var(--primary-color);
    color: var(--on-accent);
}
@media (hover: hover) {
    :root .font-size-btn:hover:not(:disabled) {
        background: var(--primary-hover);
        color: var(--on-accent);
    }
}
:root .font-size-btn:active:not(:disabled) {
    background: var(--primary-hover);
    color: var(--on-accent);
}
:root .font-size-btn:disabled {
    background: var(--tint);
    color: var(--muted);
    opacity: 1;
}
:root .font-size-value {
    min-width: 58px;
    padding: 0 6px;
    font-variant-numeric: tabular-nums;
}

/* 10.4 Share grid in Dark: the warm two-tone fill dominated the small
   icons, so thin it out there. */
[data-theme='dark'] .share-option-icon .icon {
    --icon-fill-opacity: 0.3;
}

/* 10.5 Affiliate boxes: one quiet inset for Simple and Advanced, a
   sentence-case 11px --muted label and 12.5px minimum text. */
:root .affiliate-container,
:root #affiliateAdvancedTop {
    margin: 16px auto;
    padding: 12px;
    background: var(--surface-2);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-control);
    box-shadow: none;
    max-width: 400px;
}
:root #affiliateAdvancedTop {
    margin: 0 auto 12px;
}
:root .affiliate-label {
    margin-bottom: 8px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0;
    text-transform: none;
}
:root .affiliate-product {
    font-size: 13.5px;
    border-radius: var(--radius-control);
}
:root .affiliate-product-rating,
:root .affiliate-product-callout,
:root .affiliate-product-rating .review-count {
    font-size: 12.5px;
}
:root .affiliate-product-price {
    font-size: 13.5px;
}
:root .affiliate-browse-link {
    font-size: 12.5px;
}
/* Mid-calculator pair slots: two products side by side on iPad and
   desktop (768px and up); phones show only the first. */
.affiliate-pair .affiliate-product + .affiliate-product {
    display: none;
}
@media (min-width: 768px) {
    :root .affiliate-container.affiliate-pair,
    :root #affiliateAdvancedTop.affiliate-pair {
        max-width: 760px;
    }
    .affiliate-pair .affiliate-products {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 10px;
    }
    .affiliate-pair .affiliate-product {
        max-width: none;
    }
    .affiliate-pair .affiliate-product + .affiliate-product {
        display: flex;
    }
}
/* "Shop pizza ovens" under Oven type */
:root .oven-shop-link,
:root .form-group > a[href$='pizza-tools/#ovens'] {
    display: block;
    margin-top: 4px;
    font-size: 12.5px;
}

/* 10.6 Units segmented control (Settings): two labelled options instead of
   an on/off switch, which read as "on" when set to °F. The hidden
   #tempToggle still carries the conversion logic. */
.units-segment {
    display: inline-flex;
    flex: none;
    height: 44px;
    border: 1.5px solid var(--control-border);
    border-radius: var(--radius-control);
    background: var(--input-bg);
    overflow: hidden;
}
.units-segment .units-seg {
    min-width: 44px;
    margin: 0;
    padding: 0 14px;
    border: 0;
    border-radius: 0;
    background: transparent;
    color: var(--muted);
    font: inherit;
    font-size: 0.929em;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
}
.units-segment .units-seg.active {
    background: var(--primary-color);
    color: var(--on-accent);
}
.units-segment .units-seg:focus-visible {
    outline-offset: -4px;
    outline-color: var(--accent-ink);
}
.units-segment .units-seg.active:focus-visible {
    outline-color: var(--on-accent);
}
@media (hover: hover) {
    .units-segment .units-seg:not(.active):hover {
        background: var(--tint);
        color: var(--accent-ink);
    }
}

/* 10.7 The dialog box takes initial focus (programmatically, never by Tab):
   no ring on the whole box; the controls inside keep theirs. */
.modal-dialog:focus,
:root .modal-dialog:focus-visible {
    /* :root .modal-dialog:focus-visible outranks section 9.4's [tabindex] ring,
       which otherwise drew a second ring around the whole dialog */
    outline: none;
}

/* 10.8 Ball size estimator out of sync (pl-x9f7). When Ball weight no
   longer matches the estimator's size, the size fields fade back (still
   usable: touching them re-estimates) and a quiet note offers the
   estimate. Not an alert: nothing is wrong, the numbers just differ. */
.preset-size-section.is-stale .preset-size-input {
    opacity: 0.45;
    transition: opacity 0.15s;
}
.preset-size-section.is-stale .preset-size-input:focus-within {
    opacity: 1;
}
@media (hover: hover) {
    .preset-size-section.is-stale .preset-size-input:hover {
        opacity: 1;
    }
}
.estimator-stale {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 8px;
    margin-top: 10px;
    padding: 9px 12px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-callout);
    background: var(--surface-2);
    color: var(--muted);
    font-size: 0.893em;
    line-height: 1.4;
}
.estimator-stale.hidden {
    display: none;
}
.estimator-stale .estimator-ic {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    color: var(--muted);
}
.estimator-stale-text {
    flex: 1 1 12em;
    min-width: 0;
}
.estimator-use-btn {
    margin-left: auto;
    padding: 6px 12px;
    min-height: 32px;
    border: 1px solid var(--control-border, var(--border-color));
    border-radius: 999px;
    background: var(--card-bg);
    color: var(--accent-ink);
    font: inherit;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
}
.estimator-use-btn:focus-visible {
    outline: 2px solid var(--accent-ink);
    outline-offset: 2px;
}
@media (hover: hover) {
    .estimator-use-btn:hover {
        background: var(--tint);
    }
}
