* { margin: 0; padding: 0; box-sizing: border-box; }
[hidden] { display: none !important; }

:root {
    --primary-dark: #0a0e27;
    --primary-light: #1a1f3a;
    --accent-blue: #0066ff;
    --accent-green: #00d084;
    --accent-warn: #f5a623;
    --accent-danger: #e85a5a;
    --text-primary: #e0e0e0;
    --text-secondary: #b0b0b0;
    --text-muted: #707080;
    --border-color: #2a2f4a;
    --background: #0d111c;
    --surface: #161b2e;
    --surface-2: #1f2540;
    --radius: 10px;
    --safe-bottom: env(safe-area-inset-bottom, 0px);
    --safe-top: env(safe-area-inset-top, 0px);
}

/* Light mode (opt-in via data-theme="light" on <html>) */
:root[data-theme="light"] {
    --primary-dark: #ffffff;
    --primary-light: #f6efe0;
    --accent-blue: #1565c0;
    --accent-green: #1f9d55;
    --accent-warn: #c77700;
    --accent-danger: #d83a3a;
    --text-primary: #1a1a1a;
    --text-secondary: #4a4a4a;
    --text-muted: #8a8a8a;
    --border-color: #e5e5e5;
    --background: #f5eddd;
    --surface: #ffffff;
    --surface-2: #f0e6d2;
}
:root[data-theme="light"] .bubble.error {
    background: rgba(216, 58, 58, 0.10);
}
:root[data-theme="light"] .bubble.user .meta {
    color: rgba(255,255,255,0.85);
}

html, body {
    height: 100%;
    background: var(--background);
    color: var(--text-primary);
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    line-height: 1.5;
    overscroll-behavior-y: contain;
    -webkit-tap-highlight-color: transparent;
    /* Lock the document root to the viewport. Without this, iOS Safari can
       let `.app-view` exceed 100dvh (because it's `min-height: 100dvh`,
       not `height`) and then the BODY becomes the scrolling container.
       That carries `.chat-form` and `.chat-scroll-bottom` off-screen with
       the page scroll, and the scroll-event listener on `.chat-log` never
       fires (the user isn't scrolling .chat-log — they're scrolling the
       body). Forcing overflow:hidden here keeps overflow inside the inner
       containers (`.chat-log` for chat, `#app-main` for other tabs). */
    overflow: hidden;
}

input, button, textarea { font: inherit; color: inherit; }

button { cursor: pointer; border: none; background: none; }

/* iOS Safari auto-zooms any focused form control whose computed font-size is
   below 16px. Every specific input rule below sets its own font-size and would
   win on specificity alone, so we use !important here — this rule's only job
   is to defeat the iOS zoom heuristic, not to participate in normal cascade.
   Desktop sizing is unchanged. */
@media (max-width: 768px) {
    input, select, textarea { font-size: 16px !important; }
}

.muted { color: var(--text-muted); font-size: 14px; }
.pantry-section-hint { margin: 4px 0 10px 0; line-height: 1.45; }
.pantry-section-hint a { color: var(--accent); text-decoration: underline; }

/* ============================================
   Login
   ============================================ */
.login-view {
    min-height: 100dvh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary-light) 100%);
}
.login-card {
    width: 100%;
    max-width: 360px;
    background: var(--surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    padding: 32px 24px;
}
.login-logo {
    display: block;
    margin: 0 auto;
    width: 200px;
    max-width: 60%;
    height: auto;
}
.login-tagline {
    text-align: center;
    color: var(--text-secondary);
    font-size: 14px;
    margin-top: 4px;
    margin-bottom: 28px;
}
.login-form { display: flex; flex-direction: column; gap: 12px; }
.login-form input {
    background: var(--background);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    padding: 12px 14px;
    color: var(--text-primary);
    font-size: 15px;
}
.login-form input:focus { outline: none; border-color: var(--accent-blue); }
.login-form button {
    background: linear-gradient(135deg, var(--accent-blue), var(--accent-green));
    color: white;
    padding: 12px;
    border-radius: 8px;
    font-weight: 600;
    margin-top: 8px;
}
.login-form button:disabled { opacity: 0.5; cursor: not-allowed; }
.login-error {
    color: var(--accent-danger);
    font-size: 13px;
    min-height: 18px;
    text-align: center;
}
.login-footer {
    margin-top: 20px;
    color: var(--text-muted);
    font-size: 12px;
    text-align: center;
}

.otp-sent-to {
    text-align: center;
    color: var(--text-muted);
    font-size: 13px;
    margin-bottom: 4px;
}
.otp-sent-to #otp-sent-to-email {
    color: var(--text-primary);
    font-weight: 500;
    margin-left: 4px;
    word-break: break-all;
}

#otp-code {
    text-align: center;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 22px;
    letter-spacing: 8px;
}

.otp-secondary-actions {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    margin-top: 4px;
}
.otp-secondary-actions .link-btn {
    background: none;
    border: none;
    color: var(--accent-blue);
    font-size: 13px;
    padding: 4px 0;
    cursor: pointer;
}
.otp-secondary-actions .link-btn:disabled {
    color: var(--text-muted);
    cursor: not-allowed;
}

.otp-expiry-hint {
    text-align: center;
    color: var(--text-muted);
    font-size: 12px;
}

/* ============================================
   App shell
   ============================================ */
.app-view {
    display: flex;
    flex-direction: column;
    /* `height` (not `min-height`) so .app-view is pinned to viewport size
       and never grows past it. Combined with `body { overflow: hidden }`,
       this guarantees the chat-log is the only place vertical overflow
       can live in the chat tab, which is what the scroll listener + the
       scroll-to-bottom button + the new-message badge all rely on. */
    height: 100dvh;
    padding-top: var(--safe-top);
}
.app-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 16px;
    background: var(--primary-dark);
    border-bottom: 1px solid var(--border-color);
    position: sticky;
    top: 0;
    z-index: 10;
}
.app-logo {
    font-size: 18px;
    font-weight: 700;
    background: linear-gradient(135deg, var(--accent-blue), var(--accent-green));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}
.header-actions {
    display: flex;
    align-items: center;
    gap: 8px;
}
.locale-select {
    background: var(--surface);
    color: var(--text-primary);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    padding: 6px 8px;
    font-size: 13px;
    cursor: pointer;
}
.locale-select:focus { outline: none; border-color: var(--accent-blue); }
.locale-wrap { position: relative; }
.locale-btn {
    font-size: 18px;
    width: 32px;
    height: 32px;
    background: none;
    border: none;
    line-height: 1;
}
.locale-menu {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    min-width: 140px;
    background: var(--surface);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    padding: 4px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.25);
    z-index: 50;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.locale-menu-item {
    background: none;
    border: none;
    color: var(--text-primary);
    text-align: left;
    padding: 8px 12px;
    font-size: 14px;
    border-radius: 6px;
    cursor: pointer;
}
.locale-menu-item:hover { background: var(--surface-2); }
.locale-menu-item.active {
    color: var(--accent-blue);
    font-weight: 600;
}
.icon-btn {
    color: var(--text-secondary);
    font-size: 22px;
    width: 36px;
    height: 36px;
    border-radius: 8px;
}
.icon-btn:hover { background: var(--surface-2); }
.theme-toggle {
    font-size: 18px;
    width: 32px;
    height: 32px;
    background: none;
    border: none;
    line-height: 1;
}
.header-icon-btn {
    font-size: 18px;
    width: 32px;
    height: 32px;
    background: none;
    border: none;
    line-height: 1;
    color: var(--text-primary);
}
.header-icon-btn:hover { background: var(--surface-2); }
.header-actions { gap: 4px; }
@media (max-width: 380px) {
    .header-icon-btn, .theme-toggle, .locale-btn { font-size: 16px; width: 28px; height: 28px; }
    .app-header { padding: 10px 8px; }
}
.text-btn {
    color: var(--text-secondary);
    background: var(--surface);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    padding: 6px 10px;
    font-size: 13px;
}
.text-btn:hover { background: var(--surface-2); color: var(--text-primary); }

#app-main {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding-bottom: calc(64px + var(--safe-bottom));
    display: flex;
    flex-direction: column;
}
#app-main > .view { flex: 0 0 auto; }
#app-main > #view-chat { flex: 1 1 auto; }
.view {
    padding: 16px;
    max-width: 720px;
    margin: 0 auto;
}
.view-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin: 8px 0 12px 0;
}
.view-header h2 { font-size: 18px; font-weight: 600; }
.link-btn { color: var(--accent-blue); font-size: 14px; }
.card-body {
    background: var(--surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    padding: 16px;
}

/* ============================================
   Bottom nav
   ============================================ */
.bottom-nav {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    display: flex;
    background: var(--primary-dark);
    border-top: 1px solid var(--border-color);
    padding-bottom: var(--safe-bottom);
    z-index: 10;
}
.nav-btn {
    flex: 1;
    padding: 14px 4px;
    color: var(--text-muted);
    font-size: 13px;
    font-weight: 500;
    border-top: 2px solid transparent;
}
.nav-btn.active {
    color: var(--accent-blue);
    border-top-color: var(--accent-blue);
}

/* ============================================
   Chat
   ============================================ */
#view-chat {
    display: flex;
    flex-direction: column;
    min-height: 0;
    padding: 0;
    max-width: 720px;
    margin: 0 auto;
    width: 100%;
    position: relative;
}
.chat-log {
    flex: 1;
    /* min-height: 0 is essential here — without it, the flex item defaults
       to min-height: auto (content-based), so .chat-log grows to fit all
       bubbles and the overflow-y: auto never triggers. The whole chat
       (including the .chat-form input) ends up taller than the viewport
       and #app-main becomes the scrolling container instead. That breaks
       three things at once: (a) chat-input sits below the viewport so
       users have to scroll to reach it, (b) the scroll-to-bottom button's
       listener is on .chat-log so it never fires, (c) _chatIsNearBottom
       queries .chat-log scroll state which is always 0. */
    min-height: 0;
    overflow-y: auto;
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.bubble {
    max-width: 85%;
    padding: 10px 14px;
    border-radius: 16px;
    white-space: pre-wrap;
    word-wrap: break-word;
    font-size: 15px;
    line-height: 1.45;
}
.bubble.user {
    background: var(--accent-blue);
    color: white;
    align-self: flex-end;
    border-bottom-right-radius: 4px;
}
.bubble.assistant {
    background: var(--surface);
    border: 1px solid var(--border-color);
    align-self: flex-start;
    border-bottom-left-radius: 4px;
    /* Assistant bubbles render markdown via innerHTML, so we drop the
       pre-wrap behavior the base .bubble rule sets — line breaks come
       from the <br> tags we emit inside <p> blocks, and we don't want
       extra whitespace collapsing rules getting in the way of the
       block-level <h3> / <ul> / <hr> elements. */
    white-space: normal;
}
.bubble.assistant > p {
    margin: 0;
}
.bubble.assistant > p + p,
.bubble.assistant > p + h3,
.bubble.assistant > p + h4,
.bubble.assistant > p + ul,
.bubble.assistant > p + hr,
.bubble.assistant > h3 + p,
.bubble.assistant > h4 + p,
.bubble.assistant > ul + p,
.bubble.assistant > hr + p {
    margin-top: 8px;
}
.bubble.assistant > h3 {
    margin: 4px 0;
    font-size: 16px;
    font-weight: 700;
    color: var(--text-primary);
}
.bubble.assistant > h4 {
    margin: 4px 0;
    font-size: 15px;
    font-weight: 700;
    color: var(--text-primary);
}
.bubble.assistant > h3:first-child,
.bubble.assistant > h4:first-child,
.bubble.assistant > p:first-child,
.bubble.assistant > ul:first-child {
    margin-top: 0;
}
.bubble.assistant > ul {
    margin: 4px 0 4px 0;
    padding-left: 22px;
}
.bubble.assistant > ul > li {
    margin: 2px 0;
}
.bubble.assistant > hr {
    border: none;
    border-top: 1px solid var(--border-color);
    margin: 10px 0;
}
.bubble.assistant strong {
    font-weight: 700;
}
.bubble.system {
    align-self: center;
    background: var(--surface-2);
    color: var(--text-secondary);
    font-size: 13px;
    border-radius: 8px;
}
.bubble.error {
    align-self: center;
    background: rgba(232, 90, 90, 0.15);
    color: var(--accent-danger);
    font-size: 13px;
    border-radius: 8px;
}
/* .bubble .meta retained as no-op for legacy markup; no longer rendered. */
.bubble .meta { display: none; }

.quota-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border-color);
    font-size: 12px;
    color: var(--text-secondary);
}
.quota-bar[data-level="high"] {
    background: rgba(232, 90, 90, 0.10);
    color: var(--accent-danger);
}
.quota-bar-label {
    flex: 0 0 auto;
    white-space: nowrap;
}
.quota-bar-track {
    flex: 1 1 auto;
    height: 4px;
    background: var(--border-color);
    border-radius: 2px;
    overflow: hidden;
}
.quota-bar-fill {
    display: block;
    height: 100%;
    width: 0%;
    background: var(--accent-blue);
    transition: width 240ms ease;
}
.quota-bar[data-level="high"] .quota-bar-fill {
    background: var(--accent-danger);
}
.chat-form {
    display: flex;
    gap: 8px;
    padding: 10px 12px;
    background: var(--primary-dark);
    border-top: 1px solid var(--border-color);
    align-items: center;
}
#chat-input {
    flex: 1;
    min-width: 0;
    background: var(--surface);
    border: 1px solid var(--border-color);
    border-radius: 20px;
    padding: 10px 16px;
    color: var(--text-primary);
    font-size: 15px;
    font-family: inherit;
    line-height: 1.45;
    resize: none;
    overflow-y: auto;
    max-height: 140px;
}
#chat-input:focus { outline: none; border-color: var(--accent-blue); }

.chat-scroll-bottom {
    position: absolute;
    right: 16px;
    bottom: 76px;
    width: 38px;
    height: 38px;
    border-radius: 19px;
    background: var(--surface);
    border: 1px solid var(--border-color);
    color: var(--text-primary);
    font-size: 18px;
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
    z-index: 5;
    transition: opacity 0.2s ease, transform 0.2s ease;
}
.chat-scroll-bottom:hover {
    border-color: var(--accent-blue);
    color: var(--accent-blue);
}
.chat-scroll-bottom[hidden] {
    display: none;
}
.chat-scroll-bottom.has-unread {
    border-color: var(--accent-danger);
    color: var(--accent-danger);
}
/* Red pill badge in the top-right corner; content comes from the
   data-unread attribute set by _renderChatScrollBadge. "1+" / "9+" fit
   under the same circular layout without overflowing on small viewports. */
.chat-scroll-bottom.has-unread::after {
    content: attr(data-unread);
    position: absolute;
    top: -4px;
    right: -4px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 8px;
    background: var(--accent-danger);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    line-height: 16px;
    text-align: center;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
}
#chat-send {
    background: linear-gradient(135deg, var(--accent-blue), var(--accent-green));
    color: white;
    padding: 10px 18px;
    border-radius: 20px;
    font-weight: 600;
}
#chat-send:disabled { opacity: 0.5; }

.photo-btn {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    border-radius: 20px;
    background: var(--surface);
    border: 1px solid var(--border-color);
    color: var(--text-primary);
    font-size: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.photo-btn:hover { background: var(--surface-2); }
.photo-btn:disabled { opacity: 0.5; }

.planner-btn {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    border-radius: 20px;
    background: var(--surface);
    border: 1px solid var(--border-color);
    color: var(--text-primary);
    font-size: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.planner-btn:hover { background: var(--surface-2); }
.planner-btn:disabled { opacity: 0.5; }
.planner-btn[aria-pressed="true"] {
    background: var(--accent, #d97706);
    border-color: var(--accent, #d97706);
    color: var(--primary-dark, #0a0e27);
}

/* Inline planner preview bubble — listed below the assistant reply
   when [PLAN_NAMES] was returned (spec §5). Each row has the date,
   the proposed dish title, and a pin toggle that POSTs to /plan. */
.plan-preview {
    margin: 4px 0 12px 0;
    padding: 12px;
    border-radius: 12px;
    background: var(--surface, #1a1f3a);
    border: 1px solid var(--border-color);
}
.plan-preview-header {
    font-size: 13px;
    color: var(--text-secondary, #94a3b8);
    margin: 0 0 8px 0;
}
.plan-preview-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 4px;
    border-top: 1px solid var(--border-color);
}
.plan-preview-row:first-of-type { border-top: 0; }
.plan-preview-date {
    flex: 0 0 80px;
    font-size: 12px;
    color: var(--text-secondary, #94a3b8);
    font-weight: 600;
}
.plan-preview-title {
    flex: 1 1 auto;
    font-size: 14px;
    color: var(--text-primary, #f1f5f9);
}
.plan-preview-pin {
    flex: 0 0 auto;
    background: transparent;
    border: 1px solid var(--border-color);
    border-radius: 16px;
    padding: 4px 10px;
    color: var(--text-primary);
    font-size: 12px;
    cursor: pointer;
}
.plan-preview-pin[aria-pressed="true"] {
    background: var(--accent, #d97706);
    border-color: var(--accent, #d97706);
    color: var(--primary-dark, #0a0e27);
}
.plan-preview-pin-all {
    margin-top: 8px;
    background: var(--accent, #d97706);
    border: 0;
    border-radius: 16px;
    padding: 6px 14px;
    color: var(--primary-dark, #0a0e27);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}
.plan-preview-pin-all:disabled { opacity: 0.5; cursor: default; }

.chat-attachments {
    display: flex;
    gap: 8px;
    padding: 8px 12px;
    background: var(--primary-dark);
    border-top: 1px solid var(--border-color);
    overflow-x: auto;
}
.chat-attachments .thumb {
    position: relative;
    flex: 0 0 auto;
    width: 64px;
    height: 64px;
    border-radius: 8px;
    overflow: hidden;
    border: 1px solid var(--border-color);
}
.chat-attachments .thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.chat-attachments .thumb .remove {
    position: absolute;
    top: 2px;
    right: 2px;
    width: 20px;
    height: 20px;
    border-radius: 10px;
    background: rgba(0, 0, 0, 0.7);
    color: white;
    font-size: 14px;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
}
.chat-attachments .thumb .remove:hover { background: var(--accent-danger); }
.chat-attachments .upload-error {
    color: var(--accent-danger);
    font-size: 13px;
    align-self: center;
}

/* ============================================
   Pantry
   ============================================ */
.section-label {
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-muted);
    margin: 14px 0 6px 0;
}
.section-label:first-child { margin-top: 0; }
.tag-list { display: flex; flex-wrap: wrap; gap: 6px; }
.tag {
    background: var(--surface-2);
    border: 1px solid var(--border-color);
    border-radius: 999px;
    padding: 4px 10px;
    font-size: 13px;
}
.tag.warn { border-color: var(--accent-warn); color: var(--accent-warn); }
.tag.danger { border-color: var(--accent-danger); color: var(--accent-danger); }
.tag.good { border-color: var(--accent-green); color: var(--accent-green); }
.tag.tag-removable { display: inline-flex; align-items: center; gap: 4px; padding-right: 4px; }
.tag-remove {
    appearance: none;
    background: transparent;
    border: 0;
    color: inherit;
    cursor: pointer;
    font-size: 16px;
    line-height: 1;
    padding: 2px 6px;
    border-radius: 999px;
    opacity: 0.55;
}
.tag-remove:hover, .tag-remove:focus-visible {
    opacity: 1;
    background: color-mix(in srgb, currentColor 14%, transparent);
    outline: none;
}
.kv-list { display: grid; grid-template-columns: 1fr auto; gap: 4px 12px; font-size: 14px; }
.kv-list dt { color: var(--text-secondary); }
.kv-list dd { text-align: right; }

/* Editable inventory rows: name | qty input | × */
.pantry-units-hint {
    font-size: 12px;
    margin: 0 0 6px;
    line-height: 1.35;
}
.pantry-row {
    display: grid;
    grid-template-columns: 1fr 110px auto;
    align-items: center;
    gap: 8px;
    padding: 4px 0;
    border-bottom: 1px solid var(--border-color);
    font-size: 14px;
}
.pantry-row:last-of-type { border-bottom: none; }
.pantry-row.needs-unit .pantry-qty {
    border-color: var(--accent-warn, #c08a2a);
}
.pantry-unit-warn {
    display: inline-block;
    margin-left: 6px;
    color: var(--accent-warn, #c08a2a);
    cursor: help;
}
.pantry-name { color: var(--text-secondary); overflow-wrap: anywhere; }
.pantry-qty,
.pantry-add-name,
.pantry-add-qty,
.shopping-add-input {
    background: var(--background);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    padding: 4px 8px;
    color: var(--text-primary);
    font-size: 13px;
    -webkit-appearance: none;
    appearance: none;
}
.pantry-qty { text-align: right; }
.pantry-row-remove {
    background: none;
    border: none;
    color: var(--text-secondary);
    font-size: 18px;
    line-height: 1;
    width: 24px;
    height: 24px;
    border-radius: 4px;
    cursor: pointer;
}
.pantry-row-remove:hover,
.pantry-row-remove:active { color: var(--accent-danger); background: var(--surface-2); }

.pantry-add-row {
    display: grid;
    grid-template-columns: 1fr 80px auto;
    gap: 8px;
    margin-top: 8px;
}
.pantry-add-row button,
.shopping-add-row button {
    background: var(--surface-2);
    border: 1px solid var(--border-color);
    color: var(--text-primary);
    border-radius: 6px;
    padding: 4px 12px;
    font-size: 13px;
    cursor: pointer;
}
.pantry-add-row button:hover,
.shopping-add-row button:hover { background: var(--accent-blue); border-color: var(--accent-blue); color: white; }

/* Add (+) button: filled green circle so it's locale-proof and clearly
   distinct from the gray × remove buttons. Width is fixed so the row
   layout doesn't shift when "Ajouter" / "追加" / "Add" would otherwise
   measure differently. */
.pantry-add-row .row-add,
.shopping-add-row .row-add,
.pref-add-row .row-add {
    background: var(--accent-green);
    border: none;
    color: white;
    border-radius: 50%;
    width: 28px;
    height: 28px;
    padding: 0;
    font-size: 20px;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
}
.pantry-add-row .row-add:hover,
.shopping-add-row .row-add:hover,
.pref-add-row .row-add:hover { background: var(--accent-green); filter: brightness(1.1); border-color: transparent; color: white; }

/* Shopping list editor */
.shopping-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.shopping-chips .chip {
    background: var(--surface-2);
    border: 1px solid var(--border-color);
    border-radius: 999px;
    padding: 4px 6px 4px 10px;
    font-size: 13px;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.shopping-chips .chip button {
    background: none;
    border: none;
    color: var(--text-secondary);
    font-size: 16px;
    line-height: 1;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    cursor: pointer;
    padding: 0;
}
.shopping-chips .chip button:hover { color: var(--accent-danger); background: var(--background); }
.shopping-add-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 8px;
    align-items: center;
}
.shopping-add-row .shopping-add-input { flex: 1 1 140px; min-width: 100px; }
.shopping-copy[disabled],
.shopping-clear[disabled] { opacity: 0.4; pointer-events: none; }
.shopping-copy-status { font-size: 12px; }

/* Preference chips (cooking_goals, kitchenware) */
.pref-hint {
    font-size: 12px;
    margin: 4px 0 8px;
    line-height: 1.4;
}
.pref-selected-row,
.pref-preset-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 8px;
}
.pref-empty { font-size: 12px; padding: 4px 0; }
.pref-chip {
    background: var(--surface-2);
    border: 1px solid var(--border-color);
    border-radius: 999px;
    padding: 4px 10px;
    font-size: 13px;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    line-height: 1.3;
}
.pref-chip.selected {
    background: var(--accent-green);
    border-color: var(--accent-green);
    color: #06231a;
    font-weight: 500;
    padding-right: 4px;
}
.pref-chip.selected button {
    background: none;
    border: none;
    color: #06231a;
    font-size: 16px;
    line-height: 1;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    cursor: pointer;
    padding: 0;
}
.pref-chip.selected button:hover { background: rgba(0, 0, 0, 0.15); }
.pref-chip.preset {
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
    font-weight: 400;
}
.pref-chip.preset:hover {
    border-color: var(--accent-green);
    color: var(--text-primary);
    background: var(--surface-2);
}
/* Icon is rendered as a CSS mask coloured by `currentColor`, so it
 * inherits the chip's text colour and always contrasts with the chip
 * background — selected (dark on green), unselected light (tan-grey on
 * cream), unselected dark (light on navy). */
.kw-icon {
    display: inline-block;
    width: 30px;
    height: 30px;
    margin-right: 4px;
    background-color: currentColor;
    -webkit-mask-position: center;
    mask-position: center;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-size: contain;
    mask-size: contain;
    flex-shrink: 0;
}
.kw-icon[data-kw="oven"]           { -webkit-mask-image: url("icons/dark/oven.png");           mask-image: url("icons/dark/oven.png"); }
.kw-icon[data-kw="microwave"]      { -webkit-mask-image: url("icons/dark/microwave.png");      mask-image: url("icons/dark/microwave.png"); }
.kw-icon[data-kw="ricecooker"]     { -webkit-mask-image: url("icons/dark/ricecooker.png");     mask-image: url("icons/dark/ricecooker.png"); }
.kw-icon[data-kw="wok"]            { -webkit-mask-image: url("icons/dark/wok.png");            mask-image: url("icons/dark/wok.png"); }
.kw-icon[data-kw="blender"]        { -webkit-mask-image: url("icons/dark/blender.png");        mask-image: url("icons/dark/blender.png"); }
.kw-icon[data-kw="fryer"]          { -webkit-mask-image: url("icons/dark/fryer.png");          mask-image: url("icons/dark/fryer.png"); }
.kw-icon[data-kw="pressurecooker"] { -webkit-mask-image: url("icons/dark/pressurecooker.png"); mask-image: url("icons/dark/pressurecooker.png"); }
.kw-icon[data-kw="robotmixer"]     { -webkit-mask-image: url("icons/dark/robotmixer.png");     mask-image: url("icons/dark/robotmixer.png"); }
.pref-add-row {
    display: flex;
    gap: 6px;
    align-items: center;
}
.pref-add-row .pref-add-input { flex: 1 1 140px; min-width: 100px; }

/* Onboarding overlay (first-login walkthrough) */
.onboarding-card {
    text-align: center;
    padding: 12px 24px 20px;
    gap: 14px;
}
.onboarding-topbar {
    display: flex;
    align-items: center;
    min-height: 32px;
    margin: 0 -8px;
}
.onboarding-skip {
    margin-left: auto;
    background: none;
    border: none;
    color: var(--text-secondary);
    font-size: 13px;
    cursor: pointer;
    padding: 6px 8px;
}
.onboarding-skip:hover { color: var(--text-primary); }
.onboarding-back {
    background: none;
    border: none;
    color: var(--text-secondary);
    font-size: 28px;
    line-height: 1;
    cursor: pointer;
    padding: 0 10px;
}
.onboarding-back:hover { color: var(--text-primary); }
.onboarding-back[hidden] { display: none; }
.onboarding-emoji {
    font-size: 56px;
    line-height: 1;
    margin: 4px auto 0;
}
.onboarding-title {
    font-size: 20px;
    font-weight: 600;
    margin: 0;
}
.onboarding-body {
    color: var(--text-secondary);
    font-size: 14px;
    line-height: 1.5;
    margin: 0 auto;
    max-width: 320px;
}
.onboarding-dots {
    display: flex;
    gap: 6px;
    justify-content: center;
    margin: 6px 0;
}
.onboarding-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--border-color);
    transition: background 0.2s ease;
}
.onboarding-dot.active { background: var(--accent-green); }
.onboarding-controls {
    display: flex;
    justify-content: center;
    align-items: center;
    margin-top: 4px;
}
.onboarding-next {
    width: 100%;
    background: var(--accent-green);
    color: white;
    border: none;
    border-radius: 999px;
    padding: 10px 18px;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
}
.onboarding-next:hover { filter: brightness(1.1); }
.onboarding-next:disabled { opacity: 0.6; cursor: default; }
.onboarding-household-form {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin: 6px 0 12px;
    text-align: left;
}
.onboarding-row {
    display: flex;
    gap: 10px;
}
.onboarding-field {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 12px;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.onboarding-field input {
    background: var(--surface-2);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    padding: 8px 10px;
    color: var(--text-primary);
    font-size: 15px;
}
.onboarding-field-label {
    font-size: 12px;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin-top: 4px;
}
.onboarding-toggle-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 0 4px;
}
.onboarding-toggle-text { flex: 1 1 auto; min-width: 0; }
.onboarding-toggle-label {
    font-size: 13px;
    color: var(--text-primary);
    font-weight: 600;
}
.onboarding-toggle-hint {
    font-size: 12px;
    color: var(--text-muted);
    margin-top: 3px;
    line-height: 1.4;
}
/* iOS-style switch. Native <input type="checkbox"> hidden behind the
   slider; checked state animates the knob to the right and recolors the
   track. Keyboard-focusable via the underlying input. */
.switch {
    position: relative;
    display: inline-block;
    flex: 0 0 auto;
    width: 44px;
    height: 24px;
    margin-top: 2px;
}
.switch input {
    opacity: 0;
    width: 0;
    height: 0;
    position: absolute;
}
.switch-slider {
    position: absolute;
    cursor: pointer;
    inset: 0;
    background: var(--surface-2);
    border: 1px solid var(--border-color);
    border-radius: 12px;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.switch-slider::before {
    content: "";
    position: absolute;
    width: 18px;
    height: 18px;
    left: 2px;
    top: 2px;
    background: var(--text-secondary);
    border-radius: 50%;
    transition: transform 0.15s ease, background 0.15s ease;
}
.switch input:checked + .switch-slider {
    background: var(--accent-green);
    border-color: var(--accent-green);
}
.switch input:checked + .switch-slider::before {
    transform: translateX(20px);
    background: #06231a;
}
.switch input:focus-visible + .switch-slider {
    outline: 2px solid var(--accent-blue);
    outline-offset: 2px;
}
.onboarding-chip-row {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}
.onboarding-chip {
    padding: 6px 12px;
    border-radius: 14px;
    background: var(--surface-2);
    color: var(--text-secondary);
    border: 1px solid var(--border-color);
    font-size: 13px;
    cursor: pointer;
}
.onboarding-chip:hover { color: var(--text-primary); }
.onboarding-chip.is-on {
    background: var(--accent-green);
    color: #06231a;
    border-color: var(--accent-green);
}
.onboarding-form-status {
    font-size: 12px;
    min-height: 0;
    color: var(--text-muted);
}
.onboarding-form-status.warn { color: var(--accent-danger); }
.onboarding-form-status:empty { display: none; }

/* ============================================
   Soft-lock (demo expired / subscription lapsed)
   ============================================ */
.lock-banner {
    background: linear-gradient(90deg, #4a2a0e, #5a3010);
    color: #ffd9a8;
    border-bottom: 1px solid #6a3a14;
    padding: 10px 16px;
    font-size: 13px;
    line-height: 1.4;
    text-align: center;
}
.lock-banner-text { display: block; margin-bottom: 8px; }
.lock-banner-actions {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 6px 8px;
    justify-content: center;
    max-width: 360px;
    margin: 0 auto;
}
.lock-banner-actions button,
.sub-banner-actions button {
    background: #ffb066;
    color: #1a0e00;
    border: none;
    border-radius: 6px;
    padding: 6px 14px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}
.lock-banner-actions button:hover,
.sub-banner-actions button:hover { background: #ffc488; }
.lock-banner-actions button[disabled],
.sub-banner-actions button[disabled] { opacity: 0.5; cursor: progress; }

.sub-banner {
    background: linear-gradient(90deg, #2a3a5a, #34466e);
    color: #cfe0ff;
    border-bottom: 1px solid #3d527d;
    padding: 10px 16px;
    font-size: 13px;
    line-height: 1.4;
    text-align: center;
}
.sub-banner-text { display: block; margin-bottom: 8px; }
.sub-banner-actions {
    display: flex;
    gap: 8px;
    justify-content: center;
    flex-wrap: wrap;
}
body.locked .pantry-add-row,
body.locked .shopping-add-row,
body.locked .pantry-row-remove,
body.locked .shopping-chips .chip button,
body.locked .shopping-clear,
body.locked .shopping-copy { display: none !important; }
body.locked .pantry-qty { pointer-events: none; opacity: 0.6; }
body.locked .goals-form input { pointer-events: none; opacity: 0.6; }

/* ============================================
   Recipes
   ============================================ */
.recipes-filters {
    display: flex;
    gap: 6px;
    margin: 0 0 12px;
    flex-wrap: wrap;
}
.recipe-filter {
    flex: 0 0 auto;
    padding: 6px 12px;
    border-radius: 14px;
    background: var(--surface-2);
    color: var(--text-secondary);
    font-size: 13px;
    border: 1px solid var(--border-color);
    cursor: pointer;
    line-height: 1;
}
.recipe-filter:hover { color: var(--text-primary); }
.recipe-filter.is-active {
    background: var(--accent-green);
    color: #06231a;
    border-color: var(--accent-green);
}
.recipe-card {
    background: var(--surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    padding: 12px 14px;
    margin-bottom: 10px;
    overflow: hidden;
    min-width: 0;
}
.recipe-card[hidden] { display: none; }
.recipe-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    min-width: 0;
}
.recipe-toggle {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 6px;
    text-align: left;
    background: transparent;
    border: none;
    padding: 4px 0;
    color: var(--text-primary);
    cursor: pointer;
}
.recipe-toggle-caret {
    flex: 0 0 auto;
    font-size: 11px;
    color: var(--text-muted);
    width: 12px;
}
.recipe-title {
    font-size: 15px;
    font-weight: 600;
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.recipe-detail { margin-top: 8px; }
.recipe-fav {
    flex: 0 0 auto;
    width: 28px;
    height: 28px;
    border-radius: 14px;
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: 16px;
    line-height: 1;
    border: 1px solid var(--border-color);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
}
.recipe-fav:hover { color: var(--accent-danger); }
.recipe-fav.is-on {
    background: rgba(232, 90, 90, 0.16);
    color: var(--accent-danger);
    border-color: rgba(232, 90, 90, 0.4);
}
.recipe-dislike {
    flex: 0 0 auto;
    width: 28px;
    height: 28px;
    border-radius: 14px;
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: 14px;
    line-height: 1;
    border: 1px solid var(--border-color);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    filter: grayscale(1);
    opacity: 0.7;
}
.recipe-dislike:hover { opacity: 1; }
.recipe-dislike.is-on {
    background: rgba(180, 120, 30, 0.18);
    border-color: rgba(180, 120, 30, 0.45);
    filter: none;
    opacity: 1;
}
.recipe-remove {
    flex: 0 0 auto;
    width: 28px;
    height: 28px;
    border-radius: 14px;
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: 18px;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
}
.recipe-remove:hover {
    background: rgba(232, 90, 90, 0.18);
    color: var(--accent-danger);
}
.recipe-share,
.recipe-copy {
    flex: 0 0 auto;
    width: 28px;
    height: 28px;
    border-radius: 14px;
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: 14px;
    line-height: 1;
    border: 1px solid var(--border-color);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
}
.recipe-share:hover,
.recipe-copy:hover {
    background: var(--accent-green);
    color: #06231a;
    border-color: var(--accent-green);
}
.recipe-actions {
    display: flex;
    gap: 6px;
    flex: 0 0 auto;
}
.recipe-add-shopping {
    flex: 0 0 auto;
    height: 28px;
    padding: 0 10px;
    border-radius: 14px;
    background: var(--surface-2);
    color: var(--text-secondary);
    font-size: 13px;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 2px;
    border: 1px solid var(--border-color);
    cursor: pointer;
}
.recipe-add-shopping:hover {
    background: var(--accent-green);
    color: #06231a;
    border-color: var(--accent-green);
}

/* Mobile / narrow viewport: switch the recipe-card header from a single
   row to two rows so titles get full width to wrap or breathe, and the
   action buttons land on their own row right-aligned underneath. Avoids
   the "title pushes buttons off-screen" problem on phones, and lets us
   keep the buttons at their normal 28px size without clipping. */
@media (max-width: 480px) {
    /* Strip the card-body chrome around the recipes list on phones so
       cards extend to the `.view` padding (screen − 32px). On desktop
       the .card-body box still wraps the list for visual grouping.
       Explicit width:100% + box-sizing:border-box on both the wrapper
       and each card so cards render at consistent width regardless of
       expand/collapse state — without this, content reflow when the
       expanded `.recipe-detail` becomes visible can subtly change
       the rendered width of every card in the list. */
    #recipes-body.card-body {
        width: 100%;
        background: transparent;
        border: none;
        padding: 0;
        box-sizing: border-box;
    }
    .recipe-card {
        width: 100%;
        padding: 10px 12px;
        box-sizing: border-box;
    }
    .recipe-header {
        flex-direction: column;
        align-items: stretch;
        gap: 6px;
    }
    .recipe-toggle {
        width: 100%;
        padding: 2px 0;
    }
    .recipe-title {
        font-size: 14px;
        /* allow long titles to wrap to a second visual line instead of
           getting ellipsized when there's no horizontal room left. */
        white-space: normal;
    }
    .recipe-actions {
        justify-content: flex-end;
        gap: 6px;
    }
}
.recipe-shopping-status {
    font-size: 12px;
    margin: 4px 0 8px;
    min-height: 0;
    color: var(--text-muted);
    transition: color 120ms;
}
.recipe-shopping-status.good { color: var(--accent-green); }
.recipe-shopping-status.warn { color: var(--accent-danger); }
.recipe-shopping-status:empty { display: none; }
.recipe-meta {
    font-size: 12px;
    color: var(--text-muted);
    margin-bottom: 10px;
}
.recipe-section-title {
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-muted);
    margin: 10px 0 4px 0;
}
.recipe-section-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin: 10px 0 4px 0;
}
.recipe-section-header .recipe-section-title { margin: 0; }
/* Per-recipe serving picker (− N + servings). Lives in-line with the
   Ingredients section header so it reads as "this is the scale applied
   to the list below." */
.recipe-servings-picker {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
}
.recipe-serv-btn {
    width: 26px;
    height: 26px;
    border-radius: 13px;
    background: var(--surface-2);
    border: 1px solid var(--border-color);
    color: var(--text-primary);
    font-size: 16px;
    font-weight: 700;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.recipe-serv-btn:hover {
    background: var(--accent-green);
    color: #06231a;
    border-color: var(--accent-green);
}
.recipe-serv-btn:disabled {
    opacity: 0.35;
    cursor: default;
    background: var(--surface-2);
    color: var(--text-muted);
    border-color: var(--border-color);
}
.recipe-serv-count {
    min-width: 18px;
    text-align: center;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    font-size: 15px;
    color: var(--text-primary);
}
.recipe-serv-label {
    font-size: 12px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.recipe-list {
    padding-left: 18px;
    font-size: 14px;
    color: var(--text-secondary);
}
.recipe-list li { margin: 2px 0; }
.mod-note {
    font-size: 13px;
    color: var(--accent-warn);
    background: rgba(245, 166, 35, 0.08);
    border-left: 2px solid var(--accent-warn);
    padding: 4px 8px;
    margin: 4px 0;
}

/* ============================================
   Goals form
   ============================================ */
.goals-form {
    background: var(--surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    padding: 10px 12px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px 10px;
    max-width: 300px;
}
.goals-form label {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 8px;
    font-size: 11px;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.goals-form input {
    background: var(--background);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    padding: 4px 8px;
    color: var(--text-primary);
    font-size: 13px;
    width: 70px;
    text-align: right;
    -webkit-appearance: none;
    appearance: none;
}
.goals-form input:focus { outline: none; border-color: var(--accent-blue); }
.goals-form button {
    grid-column: 1 / -1;
    justify-self: end;
    background: linear-gradient(135deg, var(--accent-blue), var(--accent-green));
    color: white;
    padding: 7px 18px;
    border-radius: 8px;
    font-size: 13px;
    font-weight: 600;
    margin-top: 6px;
    min-width: 120px;
}
#goals-status { grid-column: 1 / -1; min-height: 14px; font-size: 11px; }

/* ============================================
   Nutrition rings (lightweight)
   ============================================ */
.nutri-stat {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 0;
    border-bottom: 1px solid var(--border-color);
}
.nutri-stat:last-child { border-bottom: none; }
.nutri-stat .label { font-size: 13px; color: var(--text-secondary); }
.nutri-bar {
    flex: 1;
    margin: 0 12px;
    height: 6px;
    background: var(--surface-2);
    border-radius: 3px;
    overflow: hidden;
}
.nutri-bar .fill {
    display: block;
    height: 100%;
    background: linear-gradient(90deg, var(--accent-blue), var(--accent-green));
}
.nutri-bar .fill.over { background: var(--accent-warn); }
.nutri-stat .value { font-size: 13px; font-variant-numeric: tabular-nums; min-width: 90px; text-align: right; }

/* ============================================
   FAQ
   ============================================ */
.faq-intro {
    color: var(--text-secondary);
    font-size: 14px;
    margin-bottom: 16px;
}
.faq-disclaimer {
    margin: 0 0 20px 0;
    padding: 12px 14px;
    background-color: rgba(245, 165, 36, 0.10);
    border-left: 3px solid #f5a524;
    border-radius: 4px;
    color: var(--text-secondary);
    font-size: 13px;
    line-height: 1.55;
}
.faq-disclaimer strong {
    display: block;
    color: var(--text-primary);
    margin-bottom: 6px;
    font-size: 13px;
}
.faq-disclaimer p {
    margin: 0;
}
.faq-group {
    margin-top: 28px;
}
.faq-group:first-of-type {
    margin-top: 8px;
}
.faq-group-title {
    font-size: 19px;
    font-weight: 700;
    color: var(--text-primary);
    margin: 0 0 10px 0;
    padding-bottom: 8px;
    border-bottom: 2px solid var(--accent, var(--border-color));
}
details.faq-item {
    border-bottom: 1px solid var(--border-color);
    padding: 12px 0;
}
details.faq-item:last-child { border-bottom: none; padding-bottom: 0; }
details.faq-item summary.faq-q {
    cursor: pointer;
    list-style: none;
    font-weight: 600;
    color: var(--text-primary);
    font-size: 15px;
    padding: 4px 24px 4px 0;
    position: relative;
}
details.faq-item summary.faq-q::-webkit-details-marker { display: none; }
details.faq-item summary.faq-q::after {
    content: "›";
    position: absolute;
    right: 4px;
    top: 50%;
    transform: translateY(-50%) rotate(0deg);
    transition: transform 160ms ease-out;
    color: var(--text-secondary);
    font-size: 18px;
    line-height: 1;
}
details.faq-item[open] summary.faq-q::after { transform: translateY(-50%) rotate(90deg); }
details.faq-item summary.faq-q:hover { color: var(--accent); }
details.faq-item[open] summary.faq-q { margin-bottom: 8px; }
.faq-a {
    color: var(--text-secondary);
    font-size: 14px;
    line-height: 1.6;
}
.faq-a p { margin: 0 0 10px 0; }
.faq-a p:last-child { margin-bottom: 0; }
.faq-a strong { color: var(--text-primary); }
.faq-a ul { margin: 6px 0 10px 0; padding-left: 20px; }
.faq-a li { margin-bottom: 4px; }
.faq-copyright {
    margin-top: 32px;
    padding-top: 12px;
    border-top: 1px solid var(--border-color);
    text-align: center;
    font-size: 12px;
}

/* ============================================
   Feedback modal
   ============================================ */
.modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    z-index: 100;
}
.modal-card {
    width: 100%;
    max-width: 420px;
    max-height: calc(100dvh - 32px);
    overflow-y: auto;
    background: var(--surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    padding: 20px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
/* Tablet / desktop: 420px feels cramped on iPad-landscape and wider
   screens, especially for the feedback textarea. Lift the cap so the
   modal claims more horizontal room without going edge-to-edge. Tested
   2026-05-21 — 560px still felt small on iPad landscape; bumped to
   640px. Conservative cap intentional: keeps the modal usable on Android
   tablets and iPad-mini-portrait without going edge-to-edge. */
@media (min-width: 768px) {
    .modal-card {
        max-width: 640px;
        padding: 24px;
    }
}
.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.modal-header h3 {
    font-size: 17px;
    font-weight: 600;
}
.feedback-form {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.feedback-label {
    font-size: 13px;
    color: var(--text-secondary);
    font-weight: 500;
    margin-top: 4px;
}
.feedback-select {
    width: 100%;
    padding: 8px 10px;
}
#feedback-message {
    background: var(--background);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    padding: 10px 12px;
    color: var(--text-primary);
    font-size: 14px;
    line-height: 1.5;
    resize: vertical;
    min-height: 96px;
}
#feedback-message:focus { outline: none; border-color: var(--accent-blue); }
.feedback-status {
    min-height: 18px;
    font-size: 13px;
}
.feedback-status.error { color: var(--accent-danger); }
.feedback-status.success { color: var(--accent-green); }
.feedback-submit {
    background: linear-gradient(135deg, var(--accent-blue), var(--accent-green));
    color: white;
    padding: 10px;
    border-radius: 8px;
    font-weight: 600;
    margin-top: 4px;
}
.feedback-submit:disabled { opacity: 0.5; cursor: not-allowed; }

/* ---------- step-by-step cooking mode ----------
   Full-screen overlay above the chat, large text for at-a-distance
   reading. The backdrop fills the viewport (not centered like other
   modals) so the user feels they've entered a focused cooking flow. */
.cook-mode-backdrop {
    position: fixed;
    inset: 0;
    background: var(--background);
    z-index: 200;
    display: flex;
    flex-direction: column;
    padding: 16px;
}
.cook-mode-card {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    gap: 12px;
    max-width: 720px;
    width: 100%;
    margin: 0 auto;
}
.cook-mode-topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.cook-mode-close {
    background: transparent;
    border: 1px solid var(--border-color);
    color: var(--text-primary);
    width: 36px;
    height: 36px;
    border-radius: 18px;
    font-size: 18px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
}
.cook-mode-counter {
    color: var(--text-muted);
    font-size: 14px;
    font-variant-numeric: tabular-nums;
}
.cook-mode-title {
    font-size: 18px;
    margin: 4px 0 0;
    color: var(--text-secondary);
}
.cook-mode-step {
    flex: 1 1 auto;
    /* Mobile-first: current step is dominant for at-a-distance reading. */
    font-size: clamp(26px, 6vw, 44px);
    line-height: 1.35;
    color: var(--text-primary);
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 24px 12px;
    white-space: pre-wrap;
    overflow-y: auto;
    font-weight: 500;
}
/* Tablet / desktop: owner-tested 2026-05-21 (round 3). The previous two
   rounds bumped peek font (14→18→24) but the peek still felt small
   relative to the current step. Root cause wasn't font size — it was
   the proportional layout: `.cook-mode-step` had `flex: 1 1 auto` which
   let it claim most of the vertical real estate, leaving the peek box
   crammed at the bottom of the card with lots of whitespace above the
   step. Cap step height to ~38vh so it can't dominate, trim its internal
   padding, and dress the peek section as a card with background + padding
   so it reads as an intentional "what's next" panel instead of a footer.
   Combined with peek text at 26/24, the visual ratio between current
   and peek is now roughly 1.3:1 and they share the card meaningfully. */
@media (min-width: 768px) {
    .cook-mode-step {
        font-size: clamp(28px, 3.2vw, 34px);
        /* Take content size (not all available space) and use auto margins
           on both step + progress so the step+peek group sits vertically
           centered while progress + controls stay anchored at the bottom
           of the card. Without margin-top:auto on progress, the controls
           shifted up whenever the step text was short — owner flagged
           the inconsistency on iPad landscape 2026-05-21. */
        flex: 0 1 auto;
        margin-top: auto;
        max-height: 38vh;
        padding: 12px 12px;
    }
    .cook-mode-peek {
        gap: 8px;
        padding: 14px 18px;
        background: var(--surface-2);
        border: 1px solid var(--border-color);
        border-radius: 12px;
        /* Anchor the peek + progress + controls as a group at the bottom
           of the card. Combined with `margin-top: auto` on the step above,
           free space splits evenly between (above step) and (between step
           and peek) — so step sits in the middle of the screen while
           peek/progress/controls stay clustered at the bottom regardless
           of how long the current step text is. */
        margin-top: auto;
    }
    .cook-mode-peek-label {
        font-size: 13px;
        margin-bottom: 0;
    }
    .cook-mode-peek-step {
        font-size: 26px;
        line-height: 1.4;
    }
    .cook-mode-peek-step-second {
        font-size: 24px;
        line-height: 1.4;
    }
}
.cook-mode-peek {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 12px 4px 0;
    border-top: 1px solid var(--border-color);
}
.cook-mode-peek-label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
    margin-bottom: 2px;
}
.cook-mode-peek-step {
    font-size: 14px;
    line-height: 1.45;
    color: var(--text-muted);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    text-overflow: ellipsis;
}
.cook-mode-peek-step .cook-mode-peek-num {
    color: var(--text-secondary);
    font-weight: 600;
    margin-right: 6px;
}
.cook-mode-peek-step-second {
    opacity: 0.65;
    font-size: 13px;
}
.cook-mode-progress {
    display: flex;
    gap: 4px;
    height: 4px;
    margin: 0 4px;
}
.cook-mode-progress > span {
    flex: 1 1 0;
    background: var(--surface-2);
    border-radius: 2px;
}
.cook-mode-progress > span.is-done {
    background: var(--accent-green);
}
.cook-mode-controls {
    display: flex;
    gap: 12px;
    padding-top: 4px;
}
.cook-mode-nav {
    flex: 1 1 0;
    padding: 16px 12px;
    border: 1px solid var(--border-color);
    border-radius: 12px;
    background: var(--surface-2);
    color: var(--text-primary);
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.cook-mode-nav:disabled { opacity: 0.4; cursor: default; }
.cook-mode-nav-primary {
    background: var(--accent-green);
    color: #06231a;
    border-color: var(--accent-green);
}
.recipe-cook-mode-btn,
.recipe-cooked-btn {
    margin-top: 12px;
    width: 100%;
    padding: 12px;
    border-radius: 10px;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
}
.recipe-cook-mode-btn {
    border: 1px solid var(--accent-green);
    background: transparent;
    color: var(--accent-green);
}
.recipe-cook-mode-btn:hover {
    background: var(--accent-green);
    color: #06231a;
}
.recipe-cooked-btn {
    border: 1px solid var(--border-color);
    background: var(--surface-2);
    color: var(--text-primary);
}
.recipe-cooked-btn:hover {
    background: var(--accent-green);
    color: #06231a;
    border-color: var(--accent-green);
}
.recipe-cooked-btn:disabled {
    opacity: 0.5;
    cursor: progress;
}

/* -------- Plan sheet (F2) -------- */
.plan-sheet {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
    z-index: 200;
    display: flex;
    align-items: flex-end;
    justify-content: center;
}
.plan-sheet[hidden] { display: none; }
.plan-sheet-card {
    width: 100%;
    max-width: 520px;
    max-height: 90vh;
    display: flex;
    flex-direction: column;
    background: var(--surface, #1a1f3a);
    border-radius: 16px 16px 0 0;
    border: 1px solid var(--border-color);
    border-bottom: 0;
}
.plan-sheet-topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 16px;
    border-bottom: 1px solid var(--border-color);
}
.plan-sheet-title {
    margin: 0;
    font-size: 16px;
    color: var(--text-primary);
}
.plan-sheet-body {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 8px 12px;
}
.plan-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 6px;
    border-top: 1px solid var(--border-color);
}
.plan-row:first-child { border-top: 0; }
.plan-row-date {
    flex: 0 0 88px;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-secondary, #94a3b8);
}
.plan-row-title {
    flex: 1 1 auto;
    font-size: 14px;
    color: var(--text-primary);
}
.plan-row-title.is-empty {
    color: var(--text-secondary, #94a3b8);
    font-style: italic;
}
.plan-row-built {
    flex: 0 0 auto;
    font-size: 13px;
    line-height: 1;
    padding: 0 4px;
    color: var(--text-secondary, #94a3b8);
    opacity: 0.7;
}
.plan-row-clear {
    flex: 0 0 auto;
    background: transparent;
    border: 0;
    color: var(--text-secondary, #94a3b8);
    cursor: pointer;
    font-size: 16px;
    padding: 2px 6px;
}
.plan-row-clear:hover { color: var(--text-primary); }

.plan-row-action {
    flex: 0 0 auto;
    background: transparent;
    border: 0;
    color: var(--text-secondary, #94a3b8);
    font-size: 14px;
    line-height: 1;
    padding: 4px 6px;
    cursor: pointer;
    border-radius: 6px;
}
.plan-row-action:hover {
    background: var(--surface-2, rgba(255,255,255,0.05));
    color: var(--text-primary);
}
.plan-row.is-swap-pending {
    background: rgba(217, 119, 6, 0.15);
    border-radius: 8px;
}
.plan-sheet-hint {
    padding: 8px 16px;
    font-size: 12px;
    color: var(--accent, #d97706);
    background: rgba(217, 119, 6, 0.08);
    border-top: 1px solid var(--border-color);
    text-align: center;
}

/* -------- Brand icon system (Ajito icon set 2026-06-02) -------- */
/* Each .icon[data-icon="..."] renders the matching SVG from
   web/icons/ui/, recoloured to the current text color via
   `mask-image + background-color: currentColor`. This makes the
   icons theme-aware (light/dark) without per-icon CSS rules and
   keeps the previously-emoji buttons drop-in compatible (the
   parent button's color inheritance flows through). */
.icon {
    display: inline-block;
    width: 1.1em;
    height: 1.1em;
    background-color: currentColor;
    -webkit-mask-position: center;
            mask-position: center;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
    -webkit-mask-size: contain;
            mask-size: contain;
    vertical-align: -0.18em;
    flex: 0 0 auto;
}
.icon[data-icon="globe"]      { -webkit-mask-image: url(icons/ui/globe.svg);       mask-image: url(icons/ui/globe.svg); }
.icon[data-icon="moon"]       { -webkit-mask-image: url(icons/ui/moon.svg);        mask-image: url(icons/ui/moon.svg); }
.icon[data-icon="card"]       { -webkit-mask-image: url(icons/ui/card.svg);        mask-image: url(icons/ui/card.svg); }
.icon[data-icon="feedback"]   { -webkit-mask-image: url(icons/ui/feedback.svg);    mask-image: url(icons/ui/feedback.svg); }
.icon[data-icon="power"]      { -webkit-mask-image: url(icons/ui/power.svg);       mask-image: url(icons/ui/power.svg); }
.icon[data-icon="camera"]     { -webkit-mask-image: url(icons/ui/camera.svg);      mask-image: url(icons/ui/camera.svg); }
.icon[data-icon="calendar"]   { -webkit-mask-image: url(icons/ui/calendar.svg);    mask-image: url(icons/ui/calendar.svg); }
.icon[data-icon="close"]      { -webkit-mask-image: url(icons/ui/close.svg);       mask-image: url(icons/ui/close.svg); }
.icon[data-icon="close-heavy"]{ -webkit-mask-image: url(icons/ui/closeHeavy.svg);  mask-image: url(icons/ui/closeHeavy.svg); }
.icon[data-icon="chef-hat"]   { -webkit-mask-image: url(icons/ui/chefHat.svg);     mask-image: url(icons/ui/chefHat.svg); }
.icon[data-icon="book"]       { -webkit-mask-image: url(icons/ui/book.svg);        mask-image: url(icons/ui/book.svg); }
.icon[data-icon="pot"]        { -webkit-mask-image: url(icons/ui/pot.svg);         mask-image: url(icons/ui/pot.svg); }
.icon[data-icon="egg"]        { -webkit-mask-image: url(icons/ui/egg.svg);         mask-image: url(icons/ui/egg.svg); }
.icon[data-icon="back"]       { -webkit-mask-image: url(icons/ui/back.svg);        mask-image: url(icons/ui/back.svg); }
.icon[data-icon="cart-plus"]  { -webkit-mask-image: url(icons/ui/cartPlus.svg);    mask-image: url(icons/ui/cartPlus.svg); }
.icon[data-icon="dislike"]    { -webkit-mask-image: url(icons/ui/dislike.svg);     mask-image: url(icons/ui/dislike.svg); }
.icon[data-icon="plate"]      { -webkit-mask-image: url(icons/ui/plate.svg);       mask-image: url(icons/ui/plate.svg); }
.icon[data-icon="warning"]    { -webkit-mask-image: url(icons/ui/warning.svg);     mask-image: url(icons/ui/warning.svg); }
.icon[data-icon="scroll-down"]{ -webkit-mask-image: url(icons/ui/scrollDown.svg);  mask-image: url(icons/ui/scrollDown.svg); }

/* Larger render for the onboarding hero mark — sized to match the
   original emoji's visual weight on the first card. */
.onboarding-emoji .icon {
    width: 56px;
    height: 56px;
    color: var(--accent, #d97706);
}
.plan-sheet-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 12px 16px;
    border-top: 1px solid var(--border-color);
}
.plan-sheet-primary,
.plan-sheet-secondary {
    flex: 1 1 0;
    min-width: 120px;
    padding: 10px 14px;
    border-radius: 10px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}
.plan-sheet-primary {
    background: var(--accent, #d97706);
    border: 0;
    color: var(--primary-dark, #0a0e27);
}
.plan-sheet-primary:disabled { opacity: 0.5; cursor: default; }
.plan-sheet-secondary {
    background: transparent;
    border: 1px solid var(--border-color);
    color: var(--text-primary);
}
.plan-sheet-secondary:disabled { opacity: 0.5; cursor: default; }

/* -------- Shopping review modal (F3) -------- */
/* The shopping review is launched from inside the Plan sheet
   (z-index 200) and must stack above it. The base .modal-backdrop
   sits at 100 which is fine for everything else; we override here. */
#shopping-review-modal.modal-backdrop { z-index: 250; }
.shopping-review-card {
    max-width: 560px;
    max-height: 90vh;
    display: flex;
    flex-direction: column;
}
.shopping-review-hint {
    margin: 0 0 10px 0;
    font-size: 12px;
}
.shopping-review-body {
    flex: 1 1 auto;
    overflow-y: auto;
    padding-right: 4px;
}
.shopping-bucket {
    margin-bottom: 16px;
}
.shopping-bucket-title {
    margin: 0 0 6px 0;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-secondary, #94a3b8);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.shopping-bucket-empty {
    font-size: 12px;
    color: var(--text-secondary, #94a3b8);
    font-style: italic;
    margin: 0 0 4px 0;
}
.shopping-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 0;
}
.shopping-item label {
    flex: 1 1 auto;
    font-size: 14px;
    color: var(--text-primary);
    cursor: pointer;
}
.shopping-item .shopping-item-name {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}
.shopping-item .shopping-item-qty {
    flex: 0 0 auto;
    width: 64px;
    padding: 4px 6px;
    font-size: 13px;
    border-radius: 6px;
    border: 1px solid var(--border-color);
    background: var(--surface, transparent);
    color: var(--text-primary);
    text-align: right;
    /* Strip the spinner UI on WebKit so the input stays tidy on
       mobile. Users tap to focus + type, no need for steppers. */
    -moz-appearance: textfield;
}
.shopping-item .shopping-item-qty::-webkit-outer-spin-button,
.shopping-item .shopping-item-qty::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
.shopping-item .shopping-item-unit {
    flex: 0 0 auto;
    font-size: 13px;
    color: var(--text-secondary, #94a3b8);
    min-width: 24px;
}
.shopping-item input[type="checkbox"] {
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
    accent-color: var(--accent, #d97706);
}
.shopping-item input[type="checkbox"]:checked + label { color: var(--text-primary); }
.shopping-item input[type="checkbox"]:not(:checked) + label {
    color: var(--text-secondary, #94a3b8);
    text-decoration: line-through;
}
.shopping-review-status {
    font-size: 12px;
    margin-top: 6px;
}
.shopping-review-status.warn { color: #f87171; }
.shopping-review-confirm {
    margin-top: 12px;
    background: var(--accent, #d97706);
    border: 0;
    border-radius: 10px;
    padding: 12px 16px;
    font-size: 14px;
    font-weight: 600;
    color: var(--primary-dark, #0a0e27);
    cursor: pointer;
}
.shopping-review-confirm:disabled { opacity: 0.5; cursor: progress; }

.shop-mode-launch-row {
    margin: 8px 0 16px 0;
    display: flex;
}
.shop-mode-launch {
    flex: 1 1 auto;
    padding: 10px 14px;
    border-radius: 10px;
    border: 1px solid var(--accent, #d97706);
    background: transparent;
    color: var(--accent, #d97706);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}
.shop-mode-launch:hover {
    background: rgba(217, 119, 6, 0.1);
}

/* Shop mode (F12) inverts strikethrough semantics vs F3:
   CHECKED  = "I picked this up"  → struck through, dim
   UNCHECKED = "still need this"  → normal weight, full color
   Selectors must match the base rule's structure (input[type] + label
   sibling combinator) to beat it on specificity. */
.shopping-item.shop-mode input[type="checkbox"]:not(:checked) + label {
    text-decoration: none;
    color: var(--text-primary);
}
.shopping-item.shop-mode input[type="checkbox"]:checked + label {
    text-decoration: line-through;
    color: var(--text-secondary, #94a3b8);
}
