/* game.css — "Sands of Mali" desert game UI */

.game-host {
    position: relative;
    width: 100%;
    height: min(72vh, 720px);
    min-height: 420px;
    border-radius: var(--radius);
    overflow: hidden;
    background: #e4c79a;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.12);
}

/* Loading / error states */

.game-msg {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--s1);
    text-align: center;
    padding: var(--s6);
    color: #4a331c;
}

.game-msg-icon {
    font-size: 44px;
    line-height: 1;
    margin-bottom: var(--s1);
}

.game-msg h3 {
    font-size: 18px;
    font-weight: 700;
}

.game-msg p {
    font-size: 14px;
    opacity: 0.75;
    max-width: 32ch;
}

/* ============ GAME ROOT ============ */

.dg-root {
    position: absolute;
    inset: 0;
    overflow: hidden;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    color: #f6e6c8;
    user-select: none;
    -webkit-user-select: none;
}

.dg-canvas {
    display: block;
    width: 100%;
    height: 100%;
    cursor: crosshair;
}

.dg-root.dg-touch .dg-canvas { cursor: default; }

/* Always-on grade: a slight corner falloff and warm lift that stops the
   render looking like a raw framebuffer. */
.dg-grade {
    position: absolute;
    inset: 0;
    pointer-events: none;
    background:
        radial-gradient(ellipse at 50% 45%, rgba(0,0,0,0) 52%, rgba(60, 34, 12, 0.34) 100%),
        linear-gradient(rgba(255, 226, 170, 0.05), rgba(120, 70, 20, 0.07));
    mix-blend-mode: multiply;
}

.dg-vignette {
    position: absolute;
    inset: 0;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.4s linear;
    background:
        radial-gradient(ellipse at center, rgba(0,0,0,0) 34%, rgba(120, 30, 10, 0.55) 100%),
        linear-gradient(rgba(255, 170, 60, 0.14), rgba(255, 120, 30, 0.2));
}

/* Reticle: a restrained dot that opens into a ring near an NPC. */
.dg-reticle {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 7px;
    height: 7px;
    margin: -3.5px 0 0 -3.5px;
    border-radius: 50%;
    background: rgba(255, 244, 222, 0.62);
    box-shadow: 0 0 0 1px rgba(40, 22, 8, 0.35);
    pointer-events: none;
    transition: width 0.18s ease, height 0.18s ease, margin 0.18s ease,
                background 0.18s ease, box-shadow 0.18s ease;
}

.dg-reticle.active {
    width: 17px;
    height: 17px;
    margin: -8.5px 0 0 -8.5px;
    background: transparent;
    box-shadow: 0 0 0 1.5px rgba(255, 236, 200, 0.9), 0 0 8px rgba(0, 0, 0, 0.3);
}

.dg-root.dg-touch .dg-reticle { display: none; }

.dg-root .hidden { display: none !important; }

/* ============ HUD ============ */

.dg-hud {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    padding: var(--s3) var(--s4);
    pointer-events: none;
    gap: var(--s3);
}

.dg-purse,
.dg-kit {
    background: rgba(38, 24, 12, 0.62);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    border: 1px solid rgba(246, 226, 190, 0.18);
    border-radius: 50px;
    padding: var(--s2) var(--s3);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.2px;
    white-space: nowrap;
}

.dg-shell { margin-right: var(--s1); }
.dg-cowries { font-variant-numeric: tabular-nums; }

.dg-kit {
    display: flex;
    gap: var(--s2);
    padding: var(--s2) var(--s3);
    font-size: 16px;
}

.dg-kit-item {
    opacity: 0.28;
    filter: grayscale(1);
    transition: opacity 0.25s, filter 0.25s, transform 0.25s;
}

.dg-kit-item.has {
    opacity: 1;
    filter: none;
    transform: scale(1.12);
}

.dg-kit-camel {
    margin-left: var(--s1);
    padding-left: var(--s2);
    border-left: 1px solid rgba(246, 226, 190, 0.22);
}

/* Quest banner */

.dg-quest-banner {
    position: absolute;
    top: 58px;
    left: 50%;
    transform: translateX(-50%);
    background: rgba(38, 24, 12, 0.62);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    border: 1px solid rgba(246, 226, 190, 0.18);
    border-radius: 50px;
    padding: var(--s1) var(--s4);
    font-size: 12.5px;
    font-weight: 600;
    pointer-events: none;
    white-space: nowrap;
    max-width: 92%;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dg-quest-label {
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: 10px;
    opacity: 0.7;
    margin-right: var(--s1);
}

.dg-quest-heading { color: #f0b46a; }

/* Exposure timer */

.dg-timer {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
    pointer-events: none;
    text-shadow: 0 2px 14px rgba(0, 0, 0, 0.5);
}

.dg-timer-label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    opacity: 0.85;
}

.dg-timer-count {
    font-size: 62px;
    font-weight: 800;
    line-height: 1.05;
    font-variant-numeric: tabular-nums;
    color: #ffdca8;
}

.dg-timer-bar {
    width: 180px;
    height: 5px;
    border-radius: 50px;
    background: rgba(0, 0, 0, 0.35);
    overflow: hidden;
    margin: var(--s1) auto 0;
}

.dg-timer-fill {
    height: 100%;
    width: 100%;
    border-radius: 50px;
    background: linear-gradient(90deg, #ffcf7a, #e0552f);
    transition: width 0.15s linear;
}

/* Prompt + toast */

.dg-prompt {
    position: absolute;
    bottom: 26px;
    left: 50%;
    transform: translateX(-50%);
    background: rgba(38, 24, 12, 0.68);
    border: 1px solid rgba(246, 226, 190, 0.2);
    border-radius: 50px;
    padding: var(--s2) var(--s4);
    font-size: 13px;
    pointer-events: none;
    white-space: nowrap;
}

.dg-toast {
    position: absolute;
    bottom: 76px;
    left: 50%;
    transform: translateX(-50%);
    background: rgba(38, 24, 12, 0.8);
    border: 1px solid rgba(246, 226, 190, 0.2);
    border-radius: 14px;
    padding: var(--s2) var(--s4);
    font-size: 13px;
    line-height: 1.35;
    max-width: min(78%, 460px);
    text-align: center;
    pointer-events: none;
}

.dg-root kbd {
    display: inline-block;
    background: rgba(246, 226, 190, 0.16);
    border: 1px solid rgba(246, 226, 190, 0.3);
    border-radius: 5px;
    padding: 1px var(--s1);
    font: inherit;
    font-size: 0.86em;
    font-weight: 700;
    margin: 0 1px;
}

/* ============ OVERLAYS ============ */

.dg-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--s5);
    background: rgba(24, 14, 6, 0.62);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
    overflow-y: auto;
    z-index: 5;
}

.dg-card {
    background: linear-gradient(180deg, #fdf3e0, #f3e3c6);
    color: #3a2a15;
    border-radius: 22px;
    padding: var(--s6) var(--s6);
    max-width: 520px;
    width: 100%;
    box-shadow: 0 18px 50px rgba(0, 0, 0, 0.4);
    position: relative;
    max-height: 100%;
    overflow-y: auto;
}

.dg-kicker {
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    font-weight: 700;
    color: #a8763a;
    margin-bottom: var(--s1);
}

.dg-card h2 {
    font-size: 27px;
    font-weight: 800;
    margin-bottom: var(--s3);
    letter-spacing: -0.01em;
}

.dg-card h3 {
    font-size: 21px;
    font-weight: 800;
    margin-bottom: var(--s3);
}

.dg-card p {
    font-size: 14.5px;
    line-height: 1.55;
    margin-bottom: var(--s2);
}

.dg-hint {
    color: #6d5533;
    font-size: 13.5px !important;
}

.dg-controls-help {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s1) var(--s3);
    margin: var(--s4) 0 var(--s5);
    font-size: 12px;
    color: #6d5533;
}

.dg-controls-help kbd {
    background: #e6d5b4;
    border: 1px solid #cbb68d;
    color: #3a2a15;
}

.dg-btn {
    display: block;
    width: 100%;
    padding: var(--s3);
    border: none;
    border-radius: 14px;
    background: linear-gradient(180deg, #d08a3c, #b96f28);
    color: #fff8ea;
    font-family: inherit;
    font-size: 15.5px;
    font-weight: 700;
    cursor: pointer;
    transition: filter 0.2s, transform 0.15s;
}

.dg-btn:hover { filter: brightness(1.07); }
.dg-btn:active { transform: scale(0.985); }

.dg-close {
    position: absolute;
    top: 14px;
    right: 14px;
    width: 30px;
    height: 30px;
    border: none;
    border-radius: 50%;
    background: rgba(58, 42, 21, 0.1);
    color: #6d5533;
    font-size: 14px;
    cursor: pointer;
    line-height: 1;
}

.dg-close:hover { background: rgba(58, 42, 21, 0.18); }

.dg-speech {
    font-style: italic;
    color: #5d4527;
    border-left: 3px solid #d8bb87;
    padding-left: var(--s3);
    margin-bottom: var(--s4) !important;
}

/* ============ SHOP ============ */

.dg-shop {
    display: flex;
    flex-direction: column;
    gap: var(--s2);
}

.dg-item {
    display: flex;
    align-items: center;
    gap: var(--s3);
    padding: var(--s3) var(--s3);
    border: 1.5px solid #e0cba4;
    border-radius: 14px;
    background: rgba(255, 255, 255, 0.55);
}

.dg-item.owned {
    border-color: #a9c48f;
    background: rgba(169, 196, 143, 0.16);
}

.dg-item-icon {
    font-size: 21px;
    flex-shrink: 0;
}

.dg-item-body {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
}

.dg-item-name {
    font-size: 14.5px;
    font-weight: 700;
}

.dg-item-note {
    font-size: 12px;
    color: #7a6141;
    line-height: 1.35;
}

.dg-buy {
    flex-shrink: 0;
    border: none;
    border-radius: 50px;
    padding: var(--s2) var(--s3);
    background: #b96f28;
    color: #fff8ea;
    font-family: inherit;
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
    white-space: nowrap;
    transition: filter 0.2s;
}

.dg-buy:hover:not(:disabled) { filter: brightness(1.1); }

.dg-buy:disabled {
    background: #cbb68d;
    color: #8a765a;
    cursor: not-allowed;
}

.dg-owned {
    flex-shrink: 0;
    font-size: 12.5px;
    font-weight: 700;
    color: #5d7a42;
    white-space: nowrap;
}

.dg-ready {
    margin-top: var(--s3) !important;
    padding: var(--s2) var(--s3);
    border-radius: 12px;
    background: rgba(169, 196, 143, 0.22);
    color: #476031;
    font-weight: 600;
    font-size: 13.5px !important;
}

.dg-purse-line {
    margin-top: var(--s4);
    padding-top: var(--s3);
    border-top: 1px solid #e0cba4;
    font-size: 13px;
    color: #6d5533;
}

/* ============ QUESTS ============ */

.dg-quests {
    display: flex;
    flex-direction: column;
    gap: var(--s2);
}

.dg-quest {
    padding: var(--s3);
    border: 1.5px solid #e0cba4;
    border-radius: 14px;
    background: rgba(255, 255, 255, 0.55);
}

.dg-quest.taken {
    border-color: #a9c48f;
    background: rgba(169, 196, 143, 0.16);
}

.dg-quest-head {
    display: flex;
    align-items: baseline;
    gap: var(--s2);
    margin-bottom: var(--s1);
}

.dg-quest-name {
    font-size: 16px;
    font-weight: 800;
}

.dg-quest-dir {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: #a8763a;
    font-weight: 700;
}

.dg-quest-blurb {
    font-size: 13px !important;
    line-height: 1.5;
    color: #6d5533;
    margin-bottom: var(--s2) !important;
}

.dg-quest-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s2);
}

.dg-quest-reward {
    font-size: 12.5px;
    font-weight: 700;
    color: #8a6a2f;
}

/* ============ DEATH ============ */

.dg-death { background: rgba(60, 14, 4, 0.78); }

.dg-death-card { text-align: center; }

.dg-death-sun {
    font-size: 46px;
    line-height: 1;
    margin-bottom: var(--s2);
    color: #d9822b;
}

.dg-death-text {
    color: #6d5533;
    margin-bottom: var(--s5) !important;
}

/* ============ TOUCH CONTROLS ============ */

.dg-stick {
    position: absolute;
    left: 22px;
    bottom: 22px;
    width: 104px;
    height: 104px;
    border-radius: 50%;
    background: rgba(38, 24, 12, 0.3);
    border: 1.5px solid rgba(246, 226, 190, 0.25);
    display: flex;
    align-items: center;
    justify-content: center;
    touch-action: none;
    z-index: 3;
}

.dg-stick-nub {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: rgba(246, 226, 190, 0.5);
    border: 1.5px solid rgba(246, 226, 190, 0.7);
    pointer-events: none;
}

.dg-touch-interact {
    position: absolute;
    right: 22px;
    bottom: 40px;
    padding: var(--s4) var(--s6);
    border: 1.5px solid rgba(246, 226, 190, 0.35);
    border-radius: 50px;
    background: rgba(185, 111, 40, 0.85);
    color: #fff8ea;
    font-family: inherit;
    font-size: 15px;
    font-weight: 700;
    z-index: 3;
}

/* Touch devices: the prompt would collide with the joystick */
.dg-root.dg-touch .dg-prompt { bottom: 140px; }
.dg-root.dg-touch .dg-toast { bottom: 186px; }

/* ============ SMALL SCREENS ============ */

@media (max-width: 480px) {
    .game-host {
        height: min(64vh, 560px);
        min-height: 380px;
    }

    .dg-card { padding: var(--s5) var(--s4); }
    .dg-card h2 { font-size: 23px; }
    .dg-timer-count { font-size: 50px; }
    .dg-item-note { display: none; }
}

/* ============ JOURNEY HUD ============ */

.dg-nav {
    position: absolute;
    top: 96px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: var(--s2);
    background: rgba(38, 24, 12, 0.62);
    border: 1px solid rgba(246, 226, 190, 0.18);
    border-radius: 50px;
    padding: var(--s1) var(--s3) var(--s1) var(--s2);
    pointer-events: none;
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
}

.dg-compass {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.3);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.dg-compass-arrow {
    display: block;
    font-size: 13px;
    color: #ffd27a;
    line-height: 1;
    transform-origin: 50% 50%;
    transition: transform 0.12s linear;
}

.dg-nav-text { display: flex; flex-direction: column; line-height: 1.15; }
.dg-nav-dest { font-size: 12.5px; font-weight: 700; }
.dg-nav-dist { font-size: 10.5px; opacity: 0.75; font-variant-numeric: tabular-nums; }

.dg-meters {
    position: absolute;
    left: 16px;
    bottom: 24px;
    display: flex;
    flex-direction: column;
    gap: var(--s2);
    pointer-events: none;
}

.dg-root.dg-touch .dg-meters { bottom: 142px; }

.dg-meter { display: flex; align-items: center; gap: var(--s2); }
.dg-meter-ico { font-size: 13px; filter: drop-shadow(0 1px 2px rgba(0,0,0,0.4)); }

.dg-meter-bar {
    width: 120px;
    height: 7px;
    border-radius: 50px;
    background: rgba(38, 24, 12, 0.55);
    border: 1px solid rgba(246, 226, 190, 0.22);
    overflow: hidden;
}

.dg-meter-fill { height: 100%; border-radius: 50px; transition: width 0.2s linear; }
.dg-meter-fill.water { background: linear-gradient(90deg, #7fd4f2, #3b9fd4); }
.dg-meter-fill.food  { background: linear-gradient(90deg, #e8d08a, #c9a44e); }
.dg-meter-fill.low   { background: linear-gradient(90deg, #f2a37a, #d45b3b); }

.dg-arrival-icon, .dg-victory-icon { font-size: 46px; line-height: 1; margin-bottom: var(--s2); }

/* ---------- the painted city on arrival ----------
 * Stands in for the camel emoji above the words, never instead of them: a
 * destination with no painting keeps the emoji and the card reads exactly as
 * it did before. Wide rather than square because these are places, not props —
 * the same 320x144 banner shape the travel events use. */
.dg-arrival-art {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 10px;
    margin-bottom: var(--s2);
    image-rendering: pixelated;      /* pixel art, never smoothed on the way up */
}
.dg-arrival-reward { font-weight: 800; color: #8a6a2f; margin-bottom: var(--s4) !important; }
.dg-victory { background: rgba(24, 14, 6, 0.78); }

.dg-linkbtn {
    display: block;
    margin: var(--s2) auto 0;
    background: none;
    border: none;
    color: #8a6a2f;
    font-weight: 700;
    font-family: inherit;
    font-size: 13.5px;
    cursor: pointer;
}

/* ============ HIGH FIVE ============ */

.hf-root {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #2a2118;
    overflow: hidden;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    color: #f6e6c8;
    user-select: none;
    -webkit-user-select: none;
}

.hf-canvas {
    display: block;
    image-rendering: pixelated;
    image-rendering: crisp-edges;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.45);
}

.hf-root .hidden { display: none !important; }

.hf-hud {
    position: absolute;
    top: 12px;
    left: 12px;
    right: 12px;
    display: flex;
    justify-content: space-between;
    pointer-events: none;
}

.hf-pill {
    display: inline-flex;
    align-items: center;
    gap: var(--s1);
    background: rgba(20, 14, 8, 0.72);
    border: 1px solid rgba(246, 226, 190, 0.2);
    border-radius: 50px;
    padding: var(--s1) var(--s3);
    font-size: 12.5px;
    font-weight: 700;
}

.hf-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: #63d489;
    box-shadow: 0 0 8px #63d489;
}

.hf-roster {
    position: absolute;
    bottom: 12px;
    left: 12px;
    right: 12px;
    display: flex;
    justify-content: center;
    pointer-events: none;
}

.hf-names {
    font-weight: 600;
    max-width: 90%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.hf-alone { opacity: 0.7; font-weight: 500; }

.hf-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--s5);
    background: rgba(16, 11, 6, 0.72);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    overflow-y: auto;
    z-index: 5;
}

.hf-card {
    background: linear-gradient(180deg, #fdf3e0, #f3e3c6);
    color: #3a2a15;
    border-radius: 22px;
    padding: var(--s6) var(--s6);
    max-width: 460px;
    width: 100%;
    text-align: center;
    box-shadow: 0 18px 50px rgba(0, 0, 0, 0.45);
}

.hf-card h2 { font-size: 26px; font-weight: 800; margin-bottom: var(--s2); }
.hf-card p { font-size: 14.5px; line-height: 1.5; color: #5d4527; margin-bottom: var(--s4); }

.hf-sprites {
    display: flex;
    gap: var(--s3);
    justify-content: center;
    margin-bottom: var(--s4);
}

.hf-sprite {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--s1);
    padding: var(--s3) var(--s2);
    border: 2px solid #e0cba4;
    border-radius: 16px;
    background: rgba(255, 255, 255, 0.6);
    font-family: inherit;
    font-size: 13px;
    font-weight: 700;
    color: #3a2a15;
    cursor: pointer;
    transition: transform 0.15s, border-color 0.2s, background 0.2s;
    flex: 1;
}

.hf-sprite:hover {
    transform: translateY(-3px);
    border-color: #b96f28;
    background: #fff;
}

.hf-sprite canvas { image-rendering: pixelated; }

.hf-hint { font-size: 12px !important; color: #7a6141 !important; margin: 0 !important; }

.hf-hint kbd {
    display: inline-block;
    background: #e6d5b4;
    border: 1px solid #cbb68d;
    border-radius: 5px;
    padding: 1px var(--s1);
    font: inherit;
    font-size: 0.9em;
    font-weight: 700;
    margin: 0 1px;
}

.hf-stick {
    position: absolute;
    left: 20px;
    bottom: 52px;
    width: 96px;
    height: 96px;
    border-radius: 50%;
    background: rgba(20, 14, 8, 0.32);
    border: 1.5px solid rgba(246, 226, 190, 0.26);
    display: flex;
    align-items: center;
    justify-content: center;
    touch-action: none;
    z-index: 3;
}

.hf-stick-nub {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: rgba(246, 226, 190, 0.5);
    border: 1.5px solid rgba(246, 226, 190, 0.7);
    pointer-events: none;
}

/* ============ COZYHEALTH ============ */

.health-host {
    height: calc(100vh - 54px);
    /* iOS counts the URL bar inside 100vh, so a full-height pane
       overflows by exactly the bar and the last rows cannot be reached. */
    height: calc(100dvh - 54px);
    min-height: 320px;
    overflow-y: auto;
    background: var(--page-bg);
    -webkit-overflow-scrolling: touch;
}

.chx-root { max-width: 680px; margin: 0 auto; padding: 0 var(--s4) var(--s8); position: relative; }

.chx-tabs {
    display: flex;
    gap: var(--s1);
    padding: var(--s3) 0;
    position: sticky;
    top: 0;
    background: var(--page-bg);
    z-index: 20;
    overflow-x: auto;
    scrollbar-width: none;
}

.chx-tabs::-webkit-scrollbar { display: none; }

.chx-tab {
    flex: 1 0 auto;
    white-space: nowrap;
    padding: var(--s2) var(--s4);
    border: 1.5px solid var(--border);
    border-radius: 50px;
    background: white;
    font-family: inherit;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--text-secondary);
    cursor: pointer;
    transition: all 0.2s;
}

.chx-tab.active { background: var(--accent); color: white; border-color: var(--accent); }

.chx-hello {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s3);
    margin: var(--s1) 2px var(--s4);
}

.chx-hello h2 { font-size: 24px; font-weight: 800; letter-spacing: -0.01em; }

.chx-crumpets {
    background: rgba(var(--accent-rgb), 0.12);
    color: var(--accent);
    font-weight: 800;
    font-size: 15px;
    padding: var(--s2) var(--s4);
    border-radius: 50px;
    white-space: nowrap;
}

.chx-card {
    background: var(--card-bg);
    border: 1.5px solid var(--border);
    border-radius: var(--radius);
    padding: var(--s4);
    margin-bottom: var(--s3);
}

.chx-card h3 {
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-secondary);
    margin-bottom: var(--s3);
}

.chx-dim { color: var(--text-secondary); font-size: 13px; line-height: 1.45; }
.chx-note { margin-top: var(--s2); font-size: 11.5px; }

.chx-ring { margin-bottom: var(--s3); }

.chx-ring-bar {
    height: 8px;
    border-radius: 50px;
    background: rgba(0, 0, 0, 0.07);
    overflow: hidden;
    margin-bottom: var(--s1);
}

.chx-ring-fill {
    height: 100%;
    border-radius: 50px;
    background: var(--accent);
    transition: width 0.4s ease;
}

.chx-ring-label {
    display: flex;
    justify-content: space-between;
    font-size: 12.5px;
    font-weight: 600;
}

.chx-ring-label small { color: var(--text-secondary); font-weight: 500; }

.chx-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: var(--s3);
    margin-bottom: var(--s3);
}

.chx-stat {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    text-align: center;
    padding: var(--s3) var(--s2);
}

.chx-grid > .chx-stat { background: var(--card-bg); border: 1.5px solid var(--border); border-radius: var(--radius-sm); margin: 0; }
.chx-stat-ico { font-size: 22px; }
.chx-stat-num { font-size: 24px; font-weight: 800; color: var(--accent); line-height: 1.1; }
.chx-stat-lbl { font-size: 11.5px; color: var(--text-secondary); }

.chx-root input[type="text"],
.chx-root input[type="number"],
.chx-root select,
.chx-root textarea {
    width: 100%;
    padding: var(--s3) var(--s4);
    border: 1.5px solid var(--border);
    border-radius: 50px;
    font-size: 15px;
    font-family: inherit;
    background: white;
    outline: none;
    margin-bottom: var(--s2);
}

.chx-root textarea { border-radius: var(--radius-sm); resize: vertical; }
.chx-root input:focus, .chx-root select:focus, .chx-root textarea:focus { border-color: var(--accent); }

.chx-row { display: flex; gap: var(--s2); }
.chx-row > * { flex: 1; min-width: 0; }

.chx-btn {
    padding: var(--s3) var(--s4);
    border: 1.5px solid var(--border);
    border-radius: 50px;
    background: white;
    font-family: inherit;
    font-size: 14.5px;
    font-weight: 700;
    color: var(--text);
    cursor: pointer;
    transition: all 0.18s;
}

.chx-btn:hover { border-color: var(--accent); }
.chx-primary { width: 100%; background: var(--accent); color: white; border-color: var(--accent); }
.chx-primary:hover { filter: brightness(1.07); }

.chx-chips { display: flex; flex-wrap: wrap; gap: var(--s2); }

.chx-chip {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1px;
    padding: var(--s2) var(--s3);
    border: 1.5px solid var(--border);
    border-radius: var(--radius-sm);
    background: white;
    font-family: inherit;
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.18s;
}

.chx-chip:hover { border-color: var(--accent); transform: translateY(-1px); }
.chx-chip small { font-size: 11px; color: var(--text-secondary); font-weight: 500; }

.chx-details { margin-bottom: var(--s2); }
.chx-details summary { cursor: pointer; font-size: 13px; font-weight: 700; color: var(--text-secondary); padding: var(--s1) 0; }

.chx-servings { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--s1); padding-top: var(--s1); }

.chx-serving { display: flex; align-items: center; gap: var(--s2); font-size: 13px; }
.chx-serving span { flex: 1; }
.chx-serving input { width: 68px; flex: none; margin-bottom: 0; padding: var(--s2) var(--s2); text-align: center; }

.chx-macros { display: flex; flex-wrap: wrap; gap: var(--s3); font-size: 13.5px; font-weight: 600; margin-bottom: var(--s2); }

.chx-serving-bars { display: flex; flex-wrap: wrap; gap: var(--s2); margin-bottom: var(--s3); }

.chx-sbar {
    display: flex;
    align-items: center;
    gap: var(--s1);
    padding: var(--s1) var(--s3);
    border-radius: 50px;
    background: rgba(var(--completed-rgb), 0.14);
    font-size: 12.5px;
}

.chx-sbar.watch { background: rgba(var(--warning-rgb, 242, 153, 51), 0.16); }
.chx-sbar strong { font-weight: 800; }

.chx-item {
    display: flex;
    align-items: center;
    gap: var(--s2);
    padding: var(--s2) 0;
    border-top: 1px solid var(--border);
}

.chx-item:first-of-type { border-top: none; }
.chx-item-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.chx-item-main strong { font-size: 14.5px; }
.chx-item-main .chx-dim { font-size: 12px; }
.chx-item-num { font-weight: 700; font-size: 14px; color: var(--accent); white-space: nowrap; }

.chx-del {
    flex-shrink: 0;
    width: 26px; height: 26px;
    border: none;
    border-radius: 50%;
    background: rgba(var(--danger-rgb), 0.1);
    color: var(--danger);
    font-size: 12px;
    cursor: pointer;
}

.chx-slider { display: block; margin-bottom: var(--s3); }
.chx-slider > span { display: flex; justify-content: space-between; font-size: 13.5px; font-weight: 600; margin-bottom: var(--s1); }
.chx-slider input[type="range"] { width: 100%; accent-color: var(--accent); }

.chx-timer { text-align: center; margin-bottom: var(--s3); }

.chx-timer-face {
    font-size: 46px;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    color: var(--accent);
    margin-bottom: var(--s2);
}

.chx-med-list { border-top: 1px solid var(--border); margin-top: var(--s2); padding-top: var(--s1); }

.chx-spark { width: 100%; height: 60px; color: var(--accent); display: block; margin-bottom: 2px; }
.chx-spark-lbl { display: flex; justify-content: space-between; font-size: 11px; color: var(--text-secondary); margin-bottom: var(--s2); }

.chx-loading, .chx-empty { text-align: center; padding: var(--s8) var(--s5); color: var(--text-secondary); }
.chx-empty-card { text-align: center; }
.chx-empty-card p { margin-bottom: var(--s3); color: var(--text-secondary); font-size: 14px; }

.chx-toast {
    position: fixed;
    bottom: 24px;
    left: 50%;
    transform: translateX(-50%);
    background: rgba(38, 24, 12, 0.9);
    color: #f6e6c8;
    padding: var(--s3) var(--s5);
    border-radius: 50px;
    font-size: 14px;
    font-weight: 600;
    z-index: 400;
}

.chx-root .hidden { display: none !important; }

/* CozyHealth: person switcher, viewing banner, sharing */

.chx-people {
    display: flex;
    gap: var(--s1);
    padding: var(--s2) 0 0;
    overflow-x: auto;
    scrollbar-width: none;
}

.chx-people:empty { display: none; }
.chx-people::-webkit-scrollbar { display: none; }

.chx-person {
    flex: 0 0 auto;
    padding: var(--s1) var(--s3);
    border: 1.5px solid var(--border);
    border-radius: 50px;
    background: white;
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 700;
    color: var(--text-secondary);
    cursor: pointer;
    transition: all 0.18s;
}

.chx-person.active { background: var(--accent-secondary); color: white; border-color: var(--accent-secondary); }

.chx-viewing {
    background: rgba(var(--accent-secondary-rgb), 0.14);
    color: var(--accent-secondary);
    border-radius: var(--radius-sm);
    padding: var(--s2) var(--s3);
    font-size: 13.5px;
    font-weight: 600;
    margin-bottom: var(--s3);
}

.chx-share-list { margin-bottom: var(--s1); }
.chx-share-err { color: var(--danger); font-size: 13px; margin-top: var(--s2); }

/* ============ WRATH (ILIAD) ============ */

.il-root {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    background: #16121f;
    overflow: hidden;          /* everything fits; nothing scrolls */
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    color: #f2e3c8;
}

/* The stage takes whatever height the controls do not. min-height:0 is what
   lets a flex child actually shrink instead of forcing the parent to grow. */
.il-stage {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--s1);
}

.il-canvas {
    display: block;
    image-rendering: pixelated;
    image-rendering: crisp-edges;
    box-shadow: 0 8px 34px rgba(0,0,0,0.5);
}

.il-ui {
    flex: 0 0 auto;
    width: 100%;
    max-width: 760px;
    margin: 0 auto;
    padding: 0 var(--s3) var(--s3);
    overflow: hidden;
}

/* Wide screens: put the controls beside the battlefield so both get room. */
@media (min-width: 900px) {
    .il-root { flex-direction: row; align-items: stretch; }
    .il-stage { flex: 1 1 62%; padding: var(--s2); }
    .il-ui {
        flex: 0 0 360px;
        max-width: 360px;
        margin: 0;
        padding: var(--s3) var(--s3);
        display: flex;
        flex-direction: column;
        justify-content: center;
        background: rgba(0,0,0,0.18);
        border-left: 1px solid rgba(255,255,255,0.07);
    }
    .il-moves { grid-template-columns: 1fr; }
}

/* Menus read better centred across the whole width. */
.il-root.il-menu { flex-direction: column; }
.il-root.il-menu .il-stage { flex: 0 1 auto; max-height: 26vh; }
.il-root.il-menu .il-ui {
    flex: 1 1 auto; max-width: 780px; margin: 0 auto;
    background: none; border: none; overflow-y: auto; justify-content: flex-start;
}

/* battle HUD */
.il-hud { display: flex; flex-direction: column; gap: var(--s1); margin-bottom: var(--s2); }

.il-bar {
    background: rgba(30, 22, 40, 0.85);
    border: 2px solid #4a3a5c;
    border-radius: 10px;
    padding: var(--s1) var(--s2);
}

.il-hero-bar { border-color: #7a5c3a; }
.il-bar-name { font-size: 14px; font-weight: 800; letter-spacing: 0.01em; margin-bottom: var(--s1); }
.il-bar-name small { font-weight: 600; opacity: 0.6; font-size: 11px; }

.il-hp {
    height: 9px;
    border-radius: 50px;
    background: rgba(0,0,0,0.45);
    overflow: hidden;
    border: 1px solid rgba(255,255,255,0.12);
}

.il-hp-fill { height: 100%; background: linear-gradient(90deg,#d84a3a,#e8a04a); transition: width 0.35s ease; }
.il-hp-fill.hero { background: linear-gradient(90deg,#4aa85c,#8fd06a); }

.il-favour {
    position: relative;
    height: 15px;
    margin-top: var(--s1);
    border-radius: 50px;
    background: rgba(0,0,0,0.45);
    overflow: hidden;
    border: 1px solid rgba(255,220,140,0.25);
}

.il-favour-fill { height: 100%; background: linear-gradient(90deg,#8a6ad0,#f2d060); transition: width 0.4s ease; }
.il-favour span {
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    font-size: 8.5px; font-weight: 800; letter-spacing: 0.1em;
    text-shadow: 0 1px 2px rgba(0,0,0,0.8);
}

.il-tags { display: flex; flex-wrap: wrap; gap: var(--s1); margin-top: var(--s1); }
.il-tag {
    font-size: 9px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.06em;
    padding: 2px var(--s2); border-radius: 50px; background: rgba(255,255,255,0.14);
}
.il-tag.il-type { color: #17121d; }
.il-guarding { background: #4a7fd0; } .il-raging { background: #d0603a; }
.il-dazed { background: #9a7fd0; } .il-burning { background: #d08a3a; }
.il-exposed { background: #d04a7f; } .il-evading { background: #4ad0b0; }

.il-log {
    background: rgba(12, 9, 18, 0.9);
    border: 2px solid #4a3a5c;
    border-radius: 10px;
    padding: var(--s2) var(--s3);
    min-height: 48px;
    font-size: 12.5px;
    line-height: 1.42;
    margin-bottom: var(--s2);
}
.il-log div { opacity: 0.55; }
.il-log div:last-child { opacity: 1; font-weight: 600; }

.il-moves { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s1); }
.il-moves.busy { opacity: 0.55; pointer-events: none; }

.il-move {
    display: flex; flex-direction: column; gap: 1px;
    text-align: left;
    padding: var(--s2) var(--s3);
    border: 2px solid #5c4a70;
    border-radius: 10px;
    background: rgba(40, 30, 55, 0.9);
    color: #f2e3c8;
    font-family: inherit;
    cursor: pointer;
    transition: transform 0.12s, border-color 0.18s, background 0.18s;
}

.il-move:hover:not(:disabled) { transform: translateY(-2px); border-color: #d0a24a; background: rgba(58,44,78,0.95); }
.il-move:disabled { opacity: 0.45; cursor: default; }
.il-move-name { font-size: 12.5px; font-weight: 800; }
.il-move-meta { font-size: 10.5px; opacity: 0.72; }

.il-ult { grid-column: 1 / -1; border-color: #6a5a3a; }
.il-ult.ready {
    border-color: #f2d060;
    background: linear-gradient(90deg, rgba(120,80,180,0.5), rgba(200,150,60,0.4));
    animation: ilPulse 1.6s ease-in-out infinite;
}
@keyframes ilPulse { 0%,100% { box-shadow: 0 0 0 rgba(242,208,96,0); } 50% { box-shadow: 0 0 16px rgba(242,208,96,0.45); } }

/* panels */
.il-panel { text-align: center; padding: var(--s2) 0 var(--s5); }
.il-panel h2 { font-size: 30px; font-weight: 800; letter-spacing: 0.06em; margin-bottom: var(--s1); }
.il-sub { font-size: 14px; opacity: 0.72; line-height: 1.5; margin-bottom: var(--s4); max-width: 60ch; margin-left: auto; margin-right: auto; }

.il-heroes { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--s3); margin-bottom: var(--s4); }

.il-hero {
    display: flex; flex-direction: column; align-items: center; gap: 3px;
    padding: var(--s3) var(--s3) var(--s4);
    border: 2px solid #5c4a70;
    border-radius: 14px;
    background: rgba(34, 26, 48, 0.9);
    color: #f2e3c8;
    font-family: inherit;
    cursor: pointer;
    transition: transform 0.15s, border-color 0.2s;
}
.il-hero:hover { transform: translateY(-3px); border-color: #d0a24a; }
.il-hero canvas { image-rendering: pixelated; margin-bottom: var(--s1); }
.il-hero-name { font-size: 19px; font-weight: 800; }
.il-hero-ep { font-size: 11px; font-style: italic; opacity: 0.7; }
.il-hero-god { font-size: 10.5px; font-weight: 800; color: #f2d060; text-transform: uppercase; letter-spacing: 0.08em; margin: var(--s1) 0; }
.il-hero-blurb { font-size: 12px; line-height: 1.45; opacity: 0.62; }

.il-boons { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--s2); }
.il-boon {
    display: flex; flex-direction: column; gap: 3px;
    padding: var(--s3) var(--s3);
    border: 2px solid #6a5a3a;
    border-radius: 12px;
    background: rgba(46, 36, 26, 0.9);
    color: #f2e3c8;
    font-family: inherit;
    cursor: pointer;
    transition: transform 0.15s, border-color 0.2s;
}
.il-boon:hover { transform: translateY(-3px); border-color: #f2d060; }
.il-boon-god { font-size: 10px; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; color: #f2d060; }
.il-boon-name { font-size: 15px; font-weight: 800; }
.il-boon-desc { font-size: 12px; opacity: 0.7; line-height: 1.4; }

.il-score { margin: var(--s3) 0 var(--s4); }
.il-score span { display: block; font-size: 46px; font-weight: 800; color: #f2d060; line-height: 1; }
.il-score small { font-size: 11px; letter-spacing: 0.12em; opacity: 0.6; }

.il-board { width: 100%; border-collapse: collapse; font-size: 13px; margin-bottom: var(--s4); }
.il-board th { font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em; opacity: 0.5; padding: var(--s1) var(--s2); text-align: left; }
.il-board td { padding: var(--s2) var(--s2); border-top: 1px solid rgba(255,255,255,0.1); }
.il-board tr.top td { color: #f2d060; font-weight: 800; }

.il-row { display: flex; gap: var(--s2); justify-content: center; }

.il-btn {
    padding: var(--s3) var(--s6);
    border: 2px solid #d0a24a;
    border-radius: 50px;
    background: rgba(200,150,60,0.22);
    color: #f2e3c8;
    font-family: inherit;
    font-size: 15px;
    font-weight: 800;
    cursor: pointer;
    transition: background 0.18s;
}
.il-btn:hover { background: rgba(200,150,60,0.4); }
.il-ghost { border-color: #5c4a70; background: transparent; margin-top: var(--s1); }

@media (max-width: 520px) {
    .il-moves { grid-template-columns: 1fr; }
    .il-panel h2 { font-size: 24px; }
}


/* Very short windows: shed the least important text before scrolling. */
@media (max-height: 620px) {
    .il-move-meta { display: none; }
    .il-log { min-height: 38px; font-size: 11.5px; }
    .il-bar-name { font-size: 12.5px; }
    .il-tags { display: none; }
}

/* CozyHealth: contextual food suggestions + search */

.chx-again { border-color: rgba(var(--accent-rgb), 0.5); background: rgba(var(--accent-rgb), 0.07); }

.chx-suggest-sep {
    font-size: 10.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-secondary);
    margin: var(--s3) 0 var(--s2);
}

.chx-search { margin-top: var(--s3); }
.chx-search input { margin-bottom: 0; }

.chx-results { display: flex; flex-direction: column; gap: var(--s1); margin-top: var(--s2); max-height: 260px; overflow-y: auto; }
.chx-results:empty { display: none; }

.chx-result {
    display: flex;
    flex-direction: column;
    gap: 1px;
    text-align: left;
    padding: var(--s2) var(--s3);
    border: 1.5px solid var(--border);
    border-radius: var(--radius-sm);
    background: white;
    font-family: inherit;
    cursor: pointer;
    transition: border-color 0.16s, transform 0.14s;
}

.chx-result:hover { border-color: var(--accent); transform: translateX(2px); }
.chx-result span { font-size: 14px; font-weight: 600; }
.chx-result small { font-size: 11.5px; color: var(--text-secondary); }

/* CozyHealth — the amount bar above the food quick-select. Sets how much a
   single tap logs, so the fast path stays one tap at 100%. */
.chx-amount {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--s2);
    margin-bottom: var(--s3);
}
.chx-amount input[type="number"] {
    width: 88px;
    flex: 0 0 auto;
    margin: 0;
    text-align: right;
}
.chx-units {
    display: flex;
    flex: 0 0 auto;
    border-radius: 999px;
    overflow: hidden;
    border: 1px solid rgba(0,0,0,0.12);
}
.chx-unit {
    border: none;
    background: rgba(0,0,0,0.04);
    color: inherit;
    font: inherit;
    font-size: 0.86rem;
    padding: var(--s2) var(--s3);
    cursor: pointer;
    min-width: 40px;
}
.chx-unit + .chx-unit { border-left: 1px solid rgba(0,0,0,0.1); }
.chx-unit.active {
    background: var(--accent);
    color: #fff;
    font-weight: 600;
}
.chx-amt-hint { flex: 1 1 160px; font-size: 0.8rem; }

/* ---------- CozyCookBook ---------- */

.cookbook-host { flex: 1 1 auto; min-height: 0; overflow-y: auto; }

.ckb-root { position: relative; padding: var(--s3) var(--s3) var(--s8); max-width: 720px; margin: 0 auto; }
.ckb-loading, .ckb-empty { padding: var(--s8) var(--s2); text-align: center; color: var(--text-dim); }
.ckb-dim { color: var(--text-dim); font-size: 0.86rem; margin: var(--s1) 0 0; }
.ckb-err { color: rgb(var(--danger-rgb)); font-size: 0.84rem; margin: var(--s1) 0 0; }
.ckb-err.hidden { display: none; }

.ckb-card {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: var(--s4);
    margin-bottom: var(--s3);
}
.ckb-card h2 { margin: 0 0 2px; font-size: 1.4rem; }
.ckb-card h3 {
    margin: 0 0 var(--s2);
    font-size: 0.78rem;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--text-dim);
}

.ckb-row { display: flex; gap: var(--s2); align-items: center; margin-top: var(--s2); }
.ckb-row input, .ckb-row select { flex: 1 1 auto; margin: 0; }

.ckb-btn {
    border: 1px solid var(--border);
    background: var(--card);
    color: inherit;
    font: inherit;
    font-size: 0.9rem;
    padding: var(--s2) var(--s4);
    border-radius: 999px;
    cursor: pointer;
    flex: 0 0 auto;
}
.ckb-btn:hover { border-color: var(--accent); }
.ckb-primary { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
.ckb-ghost { background: none; }
.ckb-danger { margin-top: var(--s3); color: rgb(var(--danger-rgb)); border-color: rgba(var(--danger-rgb), 0.4); }

/* a cookbook on the shelf, with a coloured spine */
.ckb-folder, .ckb-recipe {
    display: flex;
    align-items: center;
    gap: var(--s3);
    width: 100%;
    text-align: left;
    background: none;
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: var(--s3);
    margin-bottom: var(--s2);
    cursor: pointer;
    color: inherit;
    font: inherit;
}
.ckb-folder:hover, .ckb-recipe:hover { border-color: var(--accent); }
.ckb-folder-spine {
    flex: 0 0 auto;
    width: 8px;
    align-self: stretch;
    min-height: 34px;
    border-radius: 4px;
    background: var(--accent);
}
.ckb-folder-main, .ckb-recipe-main { flex: 1 1 auto; display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.ckb-folder-main strong, .ckb-recipe-main strong { font-size: 1rem; }
.ckb-folder-main small, .ckb-recipe-main small { color: var(--text-dim); font-size: 0.8rem; }
.ckb-go { flex: 0 0 auto; color: var(--text-dim); font-size: 1.3rem; }

.ckb-crumb { display: flex; flex-wrap: wrap; gap: var(--s2); margin-bottom: var(--s3); }
.ckb-back {
    background: none; border: none; color: var(--accent);
    font: inherit; font-size: 0.9rem; cursor: pointer; padding: var(--s1) 0;
}
.ckb-back:hover { text-decoration: underline; }

/* ingredient and step checklists */
.ckb-list { list-style: none; margin: 0; padding: 0; }
.ckb-steps { counter-reset: step; }
.ckb-line { display: flex; align-items: flex-start; gap: var(--s2); padding: var(--s2) 0; border-bottom: 1px solid var(--border); }
.ckb-line:last-child { border-bottom: none; }
.ckb-line label { display: flex; align-items: flex-start; gap: var(--s2); flex: 1 1 auto; cursor: pointer; }
.ckb-line input[type="checkbox"] { margin: 3px 0 0; flex: 0 0 auto; width: 17px; height: 17px; accent-color: var(--accent); }
.ckb-steps .ckb-line label span::before {
    counter-increment: step;
    content: counter(step) ". ";
    color: var(--text-dim);
}
.ckb-line.done label span { opacity: 0.5; text-decoration: line-through; }

.ckb-del {
    flex: 0 0 auto; background: none; border: none; cursor: pointer;
    color: var(--text-dim); font-size: 0.95rem; padding: 2px var(--s1); line-height: 1;
}
.ckb-del:hover { color: rgb(var(--danger-rgb)); }

.ckb-share, .ckb-invite {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--s2); padding: var(--s2) 0; border-bottom: 1px solid var(--border);
    font-size: 0.9rem; flex-wrap: wrap;
}
.ckb-share:last-child, .ckb-invite:last-child { border-bottom: none; }
.ckb-share em { color: var(--text-dim); font-style: normal; font-size: 0.8rem; }
.ckb-invite-btns { display: flex; gap: var(--s1); }
.ckb-invites { border-color: var(--accent); }

.ckb-toast {
    position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%);
    background: rgba(20, 14, 26, 0.94); color: #fff;
    padding: var(--s2) var(--s4); border-radius: 999px; font-size: 0.88rem;
    z-index: 60; pointer-events: none;
}
.ckb-toast.hidden { display: none; }

/* CozyHealth — today's micronutrients, each against its Daily Value. */
.chx-micros { display: flex; flex-direction: column; gap: var(--s2); margin-bottom: var(--s2); }
.chx-micro { display: flex; align-items: center; gap: var(--s2); font-size: 0.86rem; }
.chx-micro-name { flex: 0 0 84px; }
.chx-micro-track {
    flex: 1 1 auto;
    height: 7px;
    border-radius: 4px;
    background: rgba(0,0,0,0.09);
    overflow: hidden;
}
.chx-micro-fill {
    display: block;
    height: 100%;
    border-radius: 4px;
    background: var(--accent);
    transition: width 0.25s ease;
}
/* value and percent get their own fixed columns, so a four-digit potassium
   figure cannot push the percentage onto a second line and break the grid */
.chx-micro-val { flex: 0 0 78px; text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.chx-micro-val em { font-style: normal; color: var(--text-dim); font-size: 0.78rem; margin-left: 1px; }
.chx-micro-pct { flex: 0 0 44px; text-align: right; color: var(--text-dim); font-variant-numeric: tabular-nums; }

/* met the target */
.chx-micro.met .chx-micro-fill { background: rgb(var(--completed-rgb)); }
/* a ceiling rather than a goal */
.chx-micro.limit .chx-micro-fill { background: rgba(var(--danger-rgb), 0.45); }
.chx-micro.over .chx-micro-fill { background: rgb(var(--danger-rgb)); }
.chx-micro.over .chx-micro-pct { color: rgb(var(--danger-rgb)); font-weight: 600; }

@media (max-width: 420px) {
    .chx-micro-name { flex: 0 0 72px; font-size: 0.82rem; }
    .chx-micro-val { flex: 0 0 70px; font-size: 0.82rem; }
    .chx-micro-pct { flex: 0 0 38px; font-size: 0.82rem; }
}

/* CozyHealth — recipes pulled in from CozyCookBook. */
.chx-recipe-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s2); }
.chx-recipe-head h3 { margin-bottom: var(--s1); }

.chx-recipe-lines {
    display: flex; flex-direction: column;
    margin: var(--s2) 0 var(--s1);
    max-height: 260px; overflow-y: auto;
}
.chx-rline {
    display: flex; align-items: baseline; gap: var(--s2);
    padding: var(--s1) 0; font-size: 0.84rem;
    border-bottom: 1px solid var(--border);
}
.chx-rline:last-child { border-bottom: none; }
.chx-rline-name  { flex: 1 1 40%; min-width: 0; }
.chx-rline-match { flex: 1 1 40%; min-width: 0; color: var(--text-dim); font-size: 0.8rem; }
.chx-rline-match em { font-style: normal; color: var(--accent); font-weight: 700; }
.chx-rline-kcal  { flex: 0 0 68px; text-align: right; font-variant-numeric: tabular-nums; }
.chx-rline.miss .chx-rline-name  { opacity: 0.55; }
.chx-rline.miss .chx-rline-match { color: rgb(var(--danger-rgb)); opacity: 0.8; }

.chx-recipe-edit { display: flex; flex-wrap: wrap; gap: var(--s2) var(--s4); margin: var(--s2) 0 var(--s2); }
.chx-recipe-edit label {
    display: flex; align-items: center; gap: var(--s2);
    font-size: 0.86rem; color: var(--text-dim);
    white-space: nowrap;
}
/* .chx-root input[type=number] sets width:100%, so match its specificity */
.chx-recipe-edit input[type="number"] {
    width: 82px; flex: 0 0 auto; margin: 0; padding: var(--s2) var(--s2); text-align: right;
}

.chx-recipe-log {
    margin-top: var(--s4); padding-top: var(--s3);
    border-top: 1px solid var(--border);
}
.chx-recipe-log .chx-unit { font-size: 0.78rem; padding: var(--s2) var(--s3); }

/* CozyCookBook — search box, and room for the drag grips. */
.ckb-searchbox {
    width: 100%;
    padding: var(--s2) var(--s4);
    border: 1.5px solid var(--border);
    border-radius: 50px;
    font: inherit;
    font-size: 15px;
    background: var(--card);
    color: inherit;
    outline: none;
}
.ckb-searchbox:focus { border-color: var(--accent); }
.ckb-folder, .ckb-recipe { touch-action: pan-y; }
.ckb-lines .ckb-line { touch-action: pan-y; }

/* ---------- Sahara map and the Oregon-Trail journey ---------- */

.dg-trail {
    align-items: stretch;
    justify-content: stretch;
    padding: 0;
    background: #221a14;
    overflow-y: auto;
}
.dg-trail-host { width: 100%; }
/* the 3D crosshair and HUD must not float over the map */
.dg-root:has(.dg-trail:not(.hidden)) .dg-reticle,
.dg-root:has(.dg-trail:not(.hidden)) .dg-hud,
.dg-root:has(.dg-trail:not(.hidden)) .dg-quest-banner,
.dg-root:has(.dg-trail:not(.hidden)) .dg-meters,
/* the thumb stick and the Talk button belong to the 3D city, not the map */
.dg-root:has(.dg-trail:not(.hidden)) .dg-stick,
.dg-root:has(.dg-trail:not(.hidden)) .dg-touch-interact,
.dg-root:has(.dg-trail:not(.hidden)) .dg-prompt { display: none; }
.dg-map-btn { width: 100%; margin: var(--s1) 0 var(--s3); }

.tr-map-screen, .tr-journey {
    max-width: 1080px;
    margin: 0 auto;
    padding: var(--s4) var(--s4) var(--s8);
    color: #f1e3c8;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
.tr-head { position: relative; margin-bottom: var(--s3); }
.tr-head h2 { margin: 0 0 var(--s1); font-size: 1.5rem; }
.tr-head p { margin: 0; max-width: 62ch; color: #cdb693; font-size: 0.9rem; line-height: 1.45; }
.tr-close { position: absolute; top: 0; right: 0; }

.tr-btn {
    border: 1px solid rgba(255,235,200,0.32);
    background: rgba(255,235,200,0.10);
    color: #f6ead2;
    font: inherit; font-size: 0.9rem;
    padding: var(--s2) var(--s4); border-radius: 8px; cursor: pointer;
}
.tr-btn:hover { background: rgba(255,235,200,0.2); }
.tr-primary { background: #c8873a; border-color: #c8873a; color: #241705; font-weight: 700; }
.tr-primary:hover { background: #dd9a48; }

.tr-map-wrap { border-radius: 12px; overflow: hidden; box-shadow: 0 10px 34px rgba(0,0,0,0.45); }
.tr-map { display: block; width: 100%; height: auto; }
.tr-sea { fill: #8db6c4; }
.tr-coast { fill: none; stroke: #5d8593; stroke-width: 1.6; }
.tr-river { fill: none; stroke: #6fa2b5; stroke-width: 3; stroke-linecap: round; opacity: 0.9; }
.tr-water-label { fill: #48707e; font-size: 13px; font-style: italic; }
.tr-sea-label { fill: #3d6470; }
.tr-region { fill: rgba(120,88,48,0.35); font-size: 28px; letter-spacing: 8px; font-weight: 700; }
.tr-region-sm { font-size: 17px; letter-spacing: 5px; }

.tr-route {
    fill: none; stroke: rgba(120,72,32,0.5);
    stroke-width: 2; stroke-dasharray: 7 5; stroke-linejoin: round;
}
.tr-route.done { stroke: rgba(60,120,70,0.75); stroke-dasharray: none; }
.tr-route.hot { stroke: #b4341f; stroke-width: 4; stroke-dasharray: none; }

.tr-hit { fill: transparent; cursor: pointer; }
.tr-dot { stroke: #3b2410; stroke-width: 1.4; pointer-events: none; }
.tr-city .tr-dot  { fill: #f3e2bd; }
.tr-oasis .tr-dot { fill: #5f9d5a; }
.tr-well .tr-dot  { fill: #7fb4c4; }
.tr-mine .tr-dot  { fill: #d8d3c8; }
.tr-label { fill: #4a3018; font-size: 11.5px; pointer-events: none; }
.tr-city .tr-label { font-weight: 700; font-size: 12.5px; }
.tr-place:hover .tr-dot, .tr-place:focus .tr-dot { stroke: #b4341f; stroke-width: 2.6; }

.tr-legend {
    display: flex; flex-wrap: wrap; gap: var(--s4);
    margin: var(--s2) 2px; font-size: 0.82rem; color: #cdb693;
}
.tr-legend span { display: flex; align-items: center; gap: var(--s1); }
.tr-key { width: 11px; height: 11px; border-radius: 50%; border: 1px solid #3b2410; }
.tr-key-city { background: #f3e2bd; } .tr-key-oasis { background: #5f9d5a; } .tr-key-mine { background: #d8d3c8; }
.tr-dim { opacity: 0.7; font-style: italic; }

.tr-routelist { display: grid; gap: var(--s2); margin-top: var(--s3); }
@media (min-width: 780px) { .tr-routelist { grid-template-columns: 1fr 1fr; } }
.tr-route-card {
    text-align: left; display: flex; flex-direction: column; gap: var(--s1);
    padding: var(--s3) var(--s4); border-radius: 12px; cursor: pointer;
    border: 1px solid rgba(255,235,200,0.18);
    background: rgba(255,240,215,0.05); color: inherit; font: inherit;
}
.tr-route-card:hover { border-color: #c8873a; background: rgba(255,240,215,0.1); }
.tr-route-card.done { opacity: 0.55; }
.tr-rc-top { display: flex; justify-content: space-between; gap: var(--s2); align-items: baseline; }
.tr-rc-reward { color: #e2b163; font-size: 0.84rem; white-space: nowrap; }
.tr-rc-sum { color: #cdb693; font-size: 0.86rem; line-height: 1.4; }
.tr-rc-meta { color: #a08a67; font-size: 0.78rem; }
.tr-rc-stops { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s1); margin-top: 2px; }
.tr-rc-stops b { color: #7d6b4e; }
.tr-chip {
    font-style: normal; font-size: 0.72rem; padding: 2px var(--s2); border-radius: 20px;
    background: rgba(255,235,200,0.09); border: 1px solid rgba(255,235,200,0.16);
}
.tr-chip.tr-mine { border-color: rgba(216,211,200,0.5); }
.tr-chip.tr-oasis { border-color: rgba(95,157,90,0.55); }

.tr-tip {
    position: fixed; left: 50%; transform: translateX(-50%); bottom: 16px; z-index: 30;
    max-width: min(560px, calc(100vw - 32px));
    display: flex; flex-direction: column; gap: var(--s1);
    padding: var(--s3) var(--s4); border-radius: 12px;
    background: rgba(28,20,14,0.96); border: 1px solid rgba(255,235,200,0.2);
    font-size: 0.86rem; line-height: 1.45; box-shadow: 0 8px 30px rgba(0,0,0,0.5);
}
.tr-tip em { color: #c8873a; font-style: normal; font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.08em; }
.tr-tip-trade { color: #cdb693; }

/* ---------- journey ---------- */
.tr-jhead { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--s3); }
.tr-jhead h2 { margin: 0 0 3px; font-size: 1.3rem; }
.tr-jhead p { margin: 0; color: #cdb693; font-size: 0.86rem; }
.tr-day { font-size: 0.95rem; color: #e2b163; white-space: nowrap; }

.tr-track {
    position: relative; height: 74px; margin: var(--s5) 0 var(--s2);
    border-top: 2px dashed rgba(255,235,200,0.28);
}
.tr-stop { position: absolute; top: -7px; transform: translateX(-50%); text-align: center; }
.tr-stop i {
    display: block; width: 12px; height: 12px; margin: 0 auto var(--s1);
    border-radius: 50%; background: #6b5638; border: 2px solid #241a12;
}
.tr-stop.past i { background: #5f9d5a; }
.tr-stop.here i { background: #e2b163; box-shadow: 0 0 0 5px rgba(226,177,99,0.25); }
.tr-stop.tr-mine i { border-radius: 2px; }
.tr-stop b {
    display: block; font-size: 0.68rem; font-weight: 600; color: #b9a179;
    max-width: 78px; line-height: 1.2;
}
.tr-stop.here b { color: #f6ead2; }
/* The marker walking the route line. Every font ships 🐪 facing left, and the
   track runs left to right, so unflipped it moonwalks from Timbuktu to Cairo —
   which is the camel you actually notice, being the big one at the top of the
   screen. scaleX(-1) turns it round; the translate has to come first or it
   mirrors about the wrong point and the marker drifts half its own width off
   the milestone it is meant to be standing on. */
.tr-caravan {
    position: absolute;
    top: -30px;
    transform: translateX(-50%) scaleX(-1);
    font-size: 1.35rem;
    transition: left 0.5s ease;
}

.tr-meters { display: flex; flex-wrap: wrap; gap: var(--s2) var(--s5); margin: var(--s1) 0 var(--s4); font-size: 0.84rem; }
.tr-meter { display: flex; align-items: center; gap: var(--s2); color: #cdb693; }
.tr-meter strong { color: #f6ead2; font-variant-numeric: tabular-nums; }
.tr-bar { display: block; width: 110px; height: 8px; border-radius: 5px; background: rgba(0,0,0,0.35); overflow: hidden; }
.tr-bar i { display: block; height: 100%; background: #6fa2b5; }
.tr-bar.low i { background: #c4503a; }

.tr-card {
    border-radius: 14px; padding: var(--s4) var(--s5);
    border: 1px solid rgba(255,235,200,0.18);
    background: rgba(255,240,215,0.06);
}
.tr-card h3 { margin: 0 0 var(--s2); font-size: 1.15rem; }
.tr-card p { margin: 0 0 var(--s2); line-height: 1.55; color: #ded0b4; }
.tr-choices { display: flex; flex-wrap: wrap; gap: var(--s2); margin-top: var(--s3); }
.tr-halt-tag {
    font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.1em;
    color: #c8873a; margin-bottom: var(--s1);
}
.tr-trade { color: #cdb693; font-size: 0.88rem; }
.tr-reward { color: #e2b163; font-weight: 600; }
.tr-halt.tr-mine { border-color: rgba(216,211,200,0.35); }
.tr-halt.tr-oasis { border-color: rgba(95,157,90,0.4); }

.tr-log { margin-top: var(--s4); font-size: 0.8rem; color: #a08a67; line-height: 1.6; }
.tr-log em { color: #c8873a; font-style: normal; }
.tr-log b { color: #c4503a; }

.tr-final { text-align: center; max-width: 620px; margin: var(--s8) auto; }
.tr-final h2 { margin: 0 0 var(--s1); font-size: 1.7rem; }
.tr-final-sub { color: #a08a67; font-size: 0.86rem; }
.tr-final.lost h2 { color: #c4503a; }

/* CozyHealth — quick fractions of a recipe. */
.chx-fracs { display: flex; flex-wrap: wrap; gap: var(--s1); margin: var(--s2) 0 var(--s1); }
.chx-frac {
    border: 1px solid var(--border);
    background: var(--card);
    color: inherit;
    font: inherit;
    font-size: 0.9rem;
    min-width: 42px;
    padding: var(--s2) var(--s2);
    border-radius: 50px;
    cursor: pointer;
}
.chx-frac:hover { border-color: var(--accent); }
.chx-frac.active { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }

/* Wrath — the page before each duel. */
.il-prelude { max-width: 640px; }
.il-pre-kicker {
    font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase;
    color: #c8873a; margin-bottom: var(--s1);
}
.il-prelude h2 { margin: 0 0 2px; font-size: 1.9rem; }
.il-pre-lead {
    font-size: 1rem; line-height: 1.62; margin: var(--s3) 0 0;
    border-left: 3px solid rgba(200,135,58,0.55); padding-left: var(--s3);
}
.il-pre-about {
    margin: var(--s4) 0 0; padding: var(--s3) var(--s4); border-radius: 10px;
    background: rgba(0,0,0,0.22);
}
.il-pre-label {
    display: block; font-size: 0.68rem; letter-spacing: 0.11em;
    text-transform: uppercase; color: #c8873a; margin-bottom: var(--s1);
}
.il-pre-about p { margin: 0; font-size: 0.92rem; line-height: 1.55; }
.il-pre-stats {
    display: flex; flex-wrap: wrap; gap: var(--s2) var(--s3); align-items: center;
    margin: var(--s4) 0 var(--s4); font-size: 0.84rem; color: #cbb89a;
}
.il-tag.il-divine { background: rgba(200,135,58,0.25); color: #f0d9a8; }
/* the prelude reads; give it the tall layout rather than the battle split */
.il-root.il-reading .il-stage { flex: 0 1 auto; max-height: 34vh; }

/* ---------- phones: all three games ---------- */
@media (max-width: 899px) {
    /* Wrath. The stage is flex:0 1 auto with a content-driven height, and the
       canvas sizes itself from the stage — which collapsed the pair to 69px
       on a phone. A floor on the stage breaks the loop. */
    /* Percentages of .il-root, not vh. vh is the window, and the root is the
       game host inside it — so with an app bar above, every vh figure here was
       measuring the wrong box and the stage came out short. The root has a
       definite height (inset: 0 on the host), so percentages resolve properly. */
    .il-root .il-stage { min-height: 26%; max-height: 42%; }
    .il-root.il-menu .il-stage    { min-height: 24%; max-height: 40%; }
    .il-root.il-reading .il-stage { min-height: 22%; max-height: 38%; }
    /* The duel HUD, four moves and the ultimate do not fit under the stage on
       a phone, and .il-root is overflow:hidden — so without this the moves
       are simply unreachable. Let the controls pane scroll on its own. */
    /* Grow into whatever the stage does not take. Without this the pane was
       content-sized and left 133px of the phone unused below the moves. */
    .il-ui { padding: 0 var(--s3) var(--s3); overflow-y: auto; -webkit-overflow-scrolling: touch;
             flex: 1 1 auto; min-height: 0; }
    .il-moves { grid-template-columns: 1fr 1fr; gap: var(--s2); }
    .il-move { padding: var(--s2) var(--s3); }
    .il-move-name { font-size: 0.92rem; }
    /* thumb-sized targets */
    .il-btn, .il-move, .il-hero { min-height: 46px; }
    .il-prelude h2 { font-size: 1.5rem; }
    .il-pre-lead { font-size: 0.94rem; padding-left: var(--s3); }

    /* High Five and Mali both want every pixel of height they can get. */
    .hf-host, .highfive-host, .mali-host, .game-host { min-height: 0; }

    /* The Sahara map is 1000px of SVG; let it scroll sideways rather than
       shrink the towns into illegibility. */
    .tr-map-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
    .tr-map { min-width: 720px; }
    .tr-head h2 { font-size: 1.2rem; }
    .tr-close { position: static; margin-top: var(--s2); width: 100%; }
    .tr-routelist { grid-template-columns: 1fr; }
    .tr-btn, .tr-route-card { min-height: 46px; }
    /* Stops are centred on their position, so the first and last labels hang
       half off the ends. Inset the track to give them room. */
    .tr-track { height: 92px; margin: var(--s5) var(--s7) var(--s2); }
    .tr-choices .tr-btn { width: 100%; }
    .tr-tip { bottom: 10px; }

}

/* Very narrow phones: the duel HUD and the trail meters need to wrap. */
@media (max-width: 420px) {
    .il-move-name { font-size: 0.86rem; }
    .il-move-meta { font-size: 0.7rem; }
    /* Tighter spacing on a narrow phone, but not smaller text — the meters
       are the numbers you are making decisions on. */
    .tr-meters { gap: var(--s1) var(--s3); font-size: 13.5px; }
    .tr-bar { width: 68px; }
}

/* ---------- Timbuktu: the town as a top-down pixel map ---------- */

.tk-root {
    position: relative;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #1b1409;
    overflow: hidden;
}

/* Nearest-neighbour on the way up, or the whole point of pixel art is lost. */
.tk-canvas {
    image-rendering: pixelated;
    display: block;
}

.tk-prompt {
    position: absolute;
    left: 50%;
    bottom: 18px;
    transform: translateX(-50%);
    padding: var(--s1) var(--s3);
    border-radius: 999px;
    background: rgba(18, 14, 10, 0.82);
    color: #f0dfb8;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.02em;
    pointer-events: none;
}

.tk-prompt kbd {
    background: #e8cf9c;
    color: #2a1e0c;
    border-radius: 4px;
    padding: 1px var(--s1);
    margin-right: var(--s1);
    font-size: 12px;
}

.tk-stick {
    position: absolute;
    left: 22px;
    bottom: 22px;
    width: 96px;
    height: 96px;
    border-radius: 50%;
    background: rgba(240, 223, 184, 0.14);
    border: 2px solid rgba(240, 223, 184, 0.32);
    touch-action: none;
}

.tk-stick-nub {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 40px;
    height: 40px;
    /* `margin: -var(--s5) 0 0 -var(--s5)` was here, and it is not valid CSS:
       a var() cannot be negated with a leading minus, it needs
       calc(var(--s5) * -1). The whole declaration was therefore dropped, so
       nothing pulled the nub back by half its width and it rested with its
       top-left corner on the centre of the base — sitting low and right, as
       though the stick were already being pushed that way before you touched
       it. Centring by transform instead holds whatever size the nub becomes;
       the drag offset in timbuktu.js composes onto this one. */
    transform: translate(-50%, -50%);
    border-radius: 50%;
    background: rgba(240, 223, 184, 0.55);
}

/* The touch build puts the prompt above the stick rather than over it. */
.tk-touch .tk-prompt { bottom: 130px; }

/* The pixel town sits over the WebGL canvas but under every overlay panel,
   so the provisioner's shop still opens on top of it. */
.dg-town2d {
    position: absolute;
    inset: 0;
    z-index: 1;
}

.dg-town2d.hidden { display: none; }

/* ---------- CozyHealth: compact quick-add + the add-food sheet ---------- */

/* The hard cap the quick row is designed around. It replaced a standing
   amount bar plus two wrapping chip grids that between them owned most of the
   first screen. One line, capped, scrolls sideways rather than growing. */
.chx-quick {
    display: flex;
    /* stretch, not center: the button fills whatever height the 5vh cap
       allows, which on a phone is about 42px — a finger. With align-items
       centre it collapsed to its text and came out 19px tall. */
    align-items: stretch;
    gap: var(--s2);
    height: 100%;
    overflow: hidden;
}

.chx-quick-strip {
    display: flex;
    align-items: center;
    gap: var(--s1);
    overflow-x: auto;
    overflow-y: hidden;
    flex: 1;
    scrollbar-width: none;
}

.chx-quick-strip::-webkit-scrollbar { display: none; }

.chx-qchip {
    flex: 0 0 auto;
    max-width: 130px;
    padding: 2px var(--s2);
    border-radius: 999px;
    border: 1px solid #e0cba4;
    background: #fffaf0;
    font: inherit;
    font-size: 11px;
    color: #4a3a20;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
}

.chx-qchip:hover { background: #fff; border-color: #b96f28; }

.chx-add-food {
    flex: 0 0 auto;
    padding: 3px var(--s3);
    border-radius: 999px;
    border: none;
    background: #b96f28;
    color: #fff;
    font: inherit;
    font-size: 12px;
    font-weight: 700;
    cursor: pointer;
}

.chx-add-food:hover { background: #a25f1f; }

.chx-quick-empty { margin: var(--s1) 0 0; font-size: 12px; }

/* The sheet. Pick the food, then say how much — the portion controls sit
   beside the food you chose rather than being a mode set beforehand. */
.chx-sheet {
    position: fixed;
    inset: 0;
    z-index: 60;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    background: rgba(30, 20, 8, 0.45);
}

.chx-sheet.hidden { display: none; }

.chx-sheet-card {
    position: relative;
    display: flex;
    flex-direction: column;
    width: min(560px, 100%);
    max-height: 82vh;
    /* The card itself does not scroll. It used to, which meant the heading and
       the search box scrolled away with the list — and with a keyboard up
       there is only a couple of hundred pixels of card to work with, so the
       first few foods went off the top and the only way back was to scroll the
       whole panel down again. What scrolls now is the list, and nothing else. */
    overflow: hidden;
    padding: var(--s5);
    border-radius: 20px 20px 0 0;
    background: #fdf6e8;
    box-shadow: 0 -8px 40px rgba(0, 0, 0, 0.25);
}

/* The stage body: the card's one growing child. Both sheets build the same
   shape — a close button positioned over a body div that holds the stage. */
.chx-sheet-card > div {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    /* Without this a flex child refuses to shrink below its content, and the
       list would push the card past its own max-height instead of scrolling. */
    min-height: 0;
    /* Stages with no list — the nutrition label especially — are tall and need
       to scroll as a whole. Where there IS a list, the rule below hands the
       scrolling to it instead so the search box can stay put. */
    overflow-y: auto;
}

.chx-sheet-card > div:has(.chx-sheet-results) { overflow: hidden; }

@media (min-width: 640px) {
    .chx-sheet { align-items: center; }
    .chx-sheet-card { border-radius: 20px; }
}

.chx-sheet-card h3 { margin: 0 0 var(--s1); }

.chx-sheet-x {
    position: absolute;
    top: 12px;
    right: 14px;
    width: 30px;
    height: 30px;
    border: none;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.06);
    font-size: 19px;
    line-height: 1;
    cursor: pointer;
}

.chx-sheet-search {
    width: 100%;
    margin: var(--s2) 0;
    padding: var(--s2) var(--s3);
    border: 2px solid #e0cba4;
    border-radius: 12px;
    font: inherit;
    background: #fff;
}

/* The only thing that scrolls on the search stage. Pinned between the search
   box above it and the Claude line below, so result one is always the first
   thing under the box you just typed in. */
.chx-sheet-results {
    display: flex;
    flex-direction: column;
    gap: var(--s1);
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    /* Room for the focus ring on the first and last rows, which a scroll
       container would otherwise clip. */
    padding: 2px;
    margin: 0 -2px;
}

/* Everything else in a stage keeps its own size. */
.chx-sheet-card > div > :where(h3, p, label, input, .chx-sheet-foot, .chx-amount,
                               .chx-fracs, .chx-nl, .chx-looking, .chx-rs-makes) {
    flex: 0 0 auto;
}

.chx-ask { border-style: dashed !important; }

.chx-sheet-foot {
    display: flex;
    align-items: center;
    gap: var(--s2);
    margin-top: var(--s3);
}

.chx-photo-btn {
    padding: var(--s2) var(--s3);
    border-radius: 999px;
    border: 1px solid #e0cba4;
    background: #fff;
    font-size: 12px;
    font-weight: 700;
    cursor: pointer;
    white-space: nowrap;
}

.chx-portion {
    display: flex;
    align-items: center;
    gap: var(--s2);
    margin: var(--s3) 0 var(--s2);
}

.chx-portion input {
    width: 96px;
    padding: var(--s2) var(--s3);
    border: 2px solid #e0cba4;
    border-radius: 12px;
    font: inherit;
    font-size: 17px;
    background: #fff;
}

.chx-portion-sum { margin: 0; font-weight: 700; color: #7a4a12; }

.chx-btn {
    flex: 1;
    padding: var(--s3) var(--s4);
    border: none;
    border-radius: 12px;
    background: #b96f28;
    color: #fff;
    font: inherit;
    font-weight: 700;
    cursor: pointer;
}

.chx-btn-ghost {
    padding: var(--s3) var(--s4);
    border: 1px solid #e0cba4;
    border-radius: 12px;
    background: #fff;
    font: inherit;
    cursor: pointer;
}

/* The 5% budget is for the whole card, not just the row inside it: the
   default .chx-card padding alone was taking this to 9% of the viewport. */
.chx-quick-card {
    padding: var(--s1) var(--s2) !important;
    margin-bottom: var(--s1) !important;
    /* A definite height, not a max: the row inside needs something to stretch
       against, and `height: 100%` against an auto-height parent resolves to
       auto, which is why the button stayed 19px tall. This also pins the card
       at exactly 5% rather than merely under it. */
    height: 5vh;
    box-sizing: border-box;
    overflow: hidden;
}

/* ---------- CozyHealth: the mood avatar ---------- */

.chx-avatar-card {
    display: flex;
    align-items: center;
    gap: var(--s4);
}

/* On a phone the figure is the thing you want to see, so it goes above the
   words rather than fighting them for a 390px row. */
@media (max-width: 560px) {
    .chx-avatar-card { flex-direction: column; text-align: center; }
    .chx-avatar-card .chx-avatar-text { align-items: center; }
}

.chx-avatar {
    image-rendering: pixelated;
    flex: 0 0 auto;
    width: 100%;
    max-width: 280px;
    height: auto;
    border-radius: 14px;
    background: linear-gradient(#fdf3df, #f4e4c4);
}

.chx-avatar-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.chx-avatar-when {
    font-size: 11px;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #a8814a;
}

.chx-avatar-text strong { font-size: 17px; color: #3a2a15; }

.chx-avatar-pick {
    display: flex;
    gap: var(--s2);
    margin-top: var(--s2);
}

.chx-avatar-opt {
    padding: 3px;
    border: 2px solid #e0cba4;
    border-radius: 10px;
    background: #fffaf0;
    line-height: 0;
    cursor: pointer;
}

.chx-avatar-opt.active { border-color: #b96f28; background: #fff; }
.chx-avatar-opt canvas { image-rendering: pixelated; }

/* ---------- native controls that were still wearing OS chrome ---------- */

/* modals.css already strips the native arrow off its selects and draws its
   own; the game apps never did, so CozyHealth and CozyCookBook were the only
   places in the app showing a platform dropdown. Same treatment, same arrow. */
.chx-root select,
.ckb-root select {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23666' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 14px center;
    padding-right: var(--s7);
}

.ckb-root select {
    padding: var(--s3) var(--s4);
    padding-right: var(--s7);
    border: 1.5px solid var(--border);
    border-radius: 50px;
    font-size: 15px;
    font-family: inherit;
    background-color: #fff;
    outline: none;
}

.ckb-root select:focus { border-color: var(--accent); }

/* Number inputs kept their spinners, which no other control in the app has. */
.chx-root input[type="number"],
.ckb-root input[type="number"] { appearance: textfield; -webkit-appearance: textfield; }

.chx-root input[type="number"]::-webkit-outer-spin-button,
.chx-root input[type="number"]::-webkit-inner-spin-button,
.ckb-root input[type="number"]::-webkit-outer-spin-button,
.ckb-root input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* ---------- Add food: a real tap target ---------- */

/* Fills the row's full height rather than sitting as a small pill inside it,
   which on a phone lands at roughly 42px — about a finger — while keeping the
   card inside its 5vh budget. The label shortens so the width goes to the
   touch area instead of the word. */
.chx-add-food {
    align-self: stretch;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--s1);
    padding: 0 var(--s4);
    min-width: 96px;
    font-size: 13px;
    line-height: 1;
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
}

.chx-add-food:active { transform: scale(0.97); }

@media (hover: none), (pointer: coarse) {
    .chx-add-food { min-width: 112px; padding: 0 var(--s5); font-size: 14px; }
    /* Chips get a bigger target too, since they are the other tap in the row. */
    .chx-qchip { padding: var(--s1) var(--s3); font-size: 12px; }
}

/* ---------- the nutrition label shown before anything is saved ---------- */

.chx-nl {
    margin: var(--s3) 0;
    padding: var(--s3) var(--s3);
    border: 2px solid #2a1e0c;
    border-radius: 10px;
    background: #fffdf7;
    font-variant-numeric: tabular-nums;
}

.chx-nl-title { font-size: 16px; font-weight: 800; color: #2a1e0c; line-height: 1.25; }
.chx-nl-serving { font-size: 12px; color: #7a6141; margin-top: 2px; }

.chx-nl-rule { height: 6px; background: #2a1e0c; margin: var(--s2) 0; border-radius: 1px; }

.chx-nl-cal {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    font-size: 24px;
    font-weight: 800;
    color: #2a1e0c;
}

.chx-nl-row {
    display: flex;
    justify-content: space-between;
    padding: 3px 0;
    font-size: 13px;
    border-bottom: 1px solid rgba(42, 30, 12, 0.12);
}

.chx-nl-row:last-of-type { border-bottom: 0; }
.chx-nl-row.indent { padding-left: var(--s4); color: #5c4a2e; }

.chx-nl-micros {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2px var(--s4);
}

.chx-nl-micro {
    display: flex;
    justify-content: space-between;
    font-size: 12px;
    color: #5c4a2e;
    padding: 2px 0;
}

.chx-nl-groups { display: flex; flex-wrap: wrap; gap: var(--s1); align-items: center; }

.chx-nl-groups-label {
    font-size: 10.5px;
    font-weight: 800;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: #a8814a;
    margin-right: 2px;
}

.chx-nl-chip {
    padding: 2px var(--s2);
    border-radius: 999px;
    background: #f1e2c4;
    font-size: 11px;
    font-weight: 700;
    color: #5c4a2e;
}

.chx-nl-note { font-size: 12px; margin: 0; }

@media (max-width: 420px) {
    .chx-nl-micros { grid-template-columns: minmax(0, 1fr); }
}

/* The 5% budget and a 44px tap target are in direct conflict: 5vh is about
   34px on a typical phone and 31px on a small one, while a finger wants 44.
   Pointer devices keep the 5% rule; touch devices get the tap target and go
   to roughly 6% instead. Deliberate, and the only rule here that bends. */
@media (hover: none), (pointer: coarse) {
    .chx-quick-card {
        height: max(5vh, 52px) !important;
        padding: var(--s1) var(--s2) !important;
    }
    .chx-add-food { font-size: 15px; border-radius: 14px; }
}

/* ---------- Sands of Mali: the view from the road ---------- */

/* The journey was a header, a rule with an emoji on it, and a text card. The
   stage gives it the horizon the caravan is actually walking towards, and
   takes the width to do it. */
.tr-stage {
    position: relative;
    margin: 0 0 var(--s2);
    border-radius: 14px;
    overflow: hidden;
    background: #0d1030;
    box-shadow: inset 0 -30px 40px -30px rgba(0, 0, 0, 0.7);
}

.tr-scene {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 2 / 1;
    image-rendering: pixelated;
}

.tr-stage-cap {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    align-items: baseline;
    gap: var(--s2);
    padding: var(--s5) var(--s3) var(--s2);
    background: linear-gradient(rgba(10, 8, 4, 0), rgba(10, 8, 4, 0.72));
    color: #f4e6c8;
    pointer-events: none;
}

.tr-stage-cap span { font-size: 1.05rem; font-weight: 800; letter-spacing: 0.01em; }
.tr-stage-cap small { font-size: 0.78rem; color: #d9c7a4; }

/* On a wide screen the scene can afford to be the thing you look at. */
@media (min-width: 720px) {
    .tr-scene { aspect-ratio: 21 / 9; }
}

/* ---------- mobile: the things a phone does that a desktop does not ---------- */

/* iOS Safari zooms the whole page in when you focus an input whose font-size
   is under 16px, and does not zoom back out afterwards. Every form field in
   the app was 15px. Only bumped on touch so the desktop sizing is untouched. */
@media (hover: none), (pointer: coarse) {
    .chx-root input[type="text"],
    .chx-root input[type="number"],
    .chx-root select,
    .chx-root textarea,
    .ckb-root input,
    .ckb-root select,
    .ckb-root textarea,
    .form-group input,
    .form-group select,
    .form-group textarea,
    .form-section input,
    .form-section select,
    .form-section textarea,
    .chx-sheet-search,
    .chx-portion input,
    #cmdk-input {
        font-size: 16px;
    }
}

/* The bottom sheet sits against the bottom edge, so on a notched phone its
   buttons land under the home indicator. */
.chx-sheet-card {
    padding-bottom: calc(20px + env(safe-area-inset-bottom, 0px));
}

.tk-stick {
    bottom: calc(22px + env(safe-area-inset-bottom, 0px));
}

/* Pull-to-refresh reloading the page mid-entry loses whatever is typed and is
   never what was wanted inside an app like this. Scroll panes keep their own
   rubber-band rather than chaining it to the page behind. */
html, body {
    overscroll-behavior-y: none;
}

.chx-sheet-card,
.cmdk-list,
.modal-sheet {
    overscroll-behavior: contain;
}


/* ---------- avatar: one figure, the other behind a button ---------- */

.chx-avatar-change {
    align-self: flex-start;
    margin-top: var(--s2);
    padding: var(--s2) var(--s3);
    border: 1.5px solid var(--border, #e0cba4);
    border-radius: 999px;
    background: #fffaf0;
    font: inherit;
    font-size: 13px;
    font-weight: 700;
    color: #6b4a1e;
    cursor: pointer;
}

.chx-avatar-change:hover { border-color: #b96f28; background: #fff; }

@media (max-width: 560px) {
    .chx-avatar-change { align-self: center; }
}

.chx-avatar-pick {
    display: flex;
    gap: var(--s2);
    margin-top: var(--s2);
}

.chx-avatar-opt {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--s1);
    padding: var(--s1) var(--s2);
    border: 2px solid var(--border, #e0cba4);
    border-radius: 12px;
    background: #fffaf0;
    font: inherit;
    font-size: 11px;
    color: #6b4a1e;
    cursor: pointer;
}

.chx-avatar-opt.active { border-color: #b96f28; background: #fff; }
.chx-avatar-opt canvas { image-rendering: pixelated; }

/* ---------- keeping sheets above the on-screen keyboard ---------- */

/* UI.watchKeyboard publishes the keyboard's height here; it stays 0 on a
   desktop and on any browser without visualViewport, so every rule below is
   a no-op there. */
:root { --keyboard-inset: 0px; }

/* Both of these are bottom sheets (align-items: flex-end), so padding at the
   bottom is what lifts the card clear of the keyboard rather than hiding
   behind it. */
.chx-sheet,
.modal-backdrop {
    /* No transition here on purpose. The keyboard brings its own animation and
       a second one racing it reads as lag, and the sheet must be clear of the
       keyboard by the time the field is focused, not 180ms afterwards. */
    padding-bottom: var(--keyboard-inset, 0px);
}

/* Lifted, the card also has less room, so it has to scroll rather than run
   off the top of the screen. */
.chx-sheet-card {
    max-height: min(82vh, calc(100dvh - var(--keyboard-inset, 0px) - 24px));
}

.modal-sheet {
    max-height: calc(100dvh - var(--keyboard-inset, 0px) - 24px);
    overflow-y: auto;
}

/* The palette is top-anchored, so the keyboard eats its list instead. Pull it
   up and shorten it so results stay visible while typing. */
.cmdk-panel {
    max-height: min(68vh, calc(100dvh - var(--keyboard-inset, 0px) - 12vh - 16px));
}

.kb-open .cmdk-panel { margin-top: 4vh; }



/* The wait while Claude reads a food, which used to be a blank sheet. */
.chx-looking {
    display: flex;
    align-items: center;
    gap: var(--s3);
    margin: var(--s4) 0;
    color: #7a6141;
    font-size: 14px;
}

.chx-looking-spin {
    flex: 0 0 auto;
    width: 22px;
    height: 22px;
    border: 3px solid rgba(185, 111, 40, 0.25);
    border-top-color: #b96f28;
    border-radius: 50%;
    animation: polish-spin 0.7s linear infinite;
}

/* ---------- the games fill the screen they were told to fill ---------- */

/* .full-host has said "fill the screen" since it was written — but it lives in
   styles.css and .game-host { height: min(72vh, 720px) } lives here, later, at
   equal specificity. So the class won the argument on paper and lost it in the
   cascade, and all three games sat in a 72%-tall card with rounded corners.
   Flex rather than a calc, so the app bar's real height is subtracted instead
   of the 54px the old calc guessed at — it is actually 71. */
#iliad-screen,
#mali-screen,
#highfive-screen {
    display: flex;
    flex-direction: column;
}

.game-host.full-host {
    flex: 1 1 auto;
    height: auto;
    min-height: 0;
    border-radius: 0;
    box-shadow: none;
}

/* ---------- a bigger figure on the health overview ---------- */

.chx-avatar {
    max-width: 360px;
}

@media (max-width: 560px) {
    /* On a phone the figure gets the card's full width; the painted art is a
       92px source, so 368 is a clean 4x of it rather than a blurry stretch. */
    .chx-avatar { max-width: 100%; width: 100%; }
    .chx-avatar-card { padding: var(--s3) !important; }
}

/* ---------- CozyCookBook: ingredients that know what they weigh ---------- */

/* The inline match list that used to sit under the ingredient box is gone —
   adding an ingredient goes through the sheet now, which reuses CozyHealth's
   .chx-sheet / .chx-result / .chx-nl rules above rather than growing a second
   set that would drift from them. */

.ckb-amt { max-width: 84px; flex: 0 0 auto !important; }

/* Full width, because it is the only thing under the list and a small button
   floating left of a lot of empty space does not read as the way in. */
.ckb-add-ing {
    width: 100%;
    margin-top: var(--s2);
    border-style: dashed;
    font-weight: 600;
}

.chx-rs-makes { display: flex; align-items: center; gap: var(--s2); margin: var(--s3) 0; font-weight: 600; }
.chx-rs-makes input { width: 76px; }

/* Where a search result came from. The Food tab searches the shared library
   and your own cookbook in one list, and which one an answer is from changes
   what it means — a library row is a generic food, a recipe is yours. */
.chx-src {
    margin-left: var(--s2);
    padding: 1px 7px;
    border-radius: 999px;
    font-size: 10px;
    font-style: normal;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    vertical-align: 1px;
    white-space: nowrap;
}
.chx-src-food   { background: rgba(120, 92, 56, 0.14); color: #7a6242; }
.chx-src-recipe { background: rgba(242, 115, 77, 0.18); color: #b4502c; }

/* "Makes N servings" on the recipe head. It reads as a sentence rather than a
   form field, because it is a fact about the recipe, not a setting. */
.ckb-servings { align-items: center; gap: var(--s2); margin: var(--s2) 0; }
.ckb-servings label { font-weight: 600; }

/* The whole-pot figures, secondary to the per-serving ones above them: a
   serving is what you eat, the pot is context. */
.ckb-whole { margin-top: var(--s2); font-size: 0.82rem; }

.ckb-portion { align-items: center; gap: var(--s2); margin-top: var(--s3); }
.ckb-portion-sum {
    margin: var(--s2) 0 0;
    font-weight: 700;
    color: #7a4a12;
}

.ckb-ing-amount { color: #8a7350; font-weight: 500; font-size: 12px; }

.ckb-ing-kcal {
    flex: 0 0 auto;
    font-size: 12px;
    font-weight: 700;
    color: #7a4a12;
    white-space: nowrap;
}

.ckb-link-food {
    flex: 0 0 auto;
    padding: 2px var(--s2);
    border: 1px dashed var(--border, #e0cba4);
    border-radius: 999px;
    background: transparent;
    font: inherit;
    font-size: 11px;
    color: #8a7350;
    cursor: pointer;
    white-space: nowrap;
}

.ckb-nutrition {
    margin-top: var(--s3);
    padding-top: var(--s3);
    border-top: 1.5px dashed var(--border, #e0cba4);
}

.ckb-nutrition-head {
    display: flex;
    align-items: baseline;
    gap: var(--s2);
    flex-wrap: wrap;
}

.ckb-nutrition-head strong { font-size: 20px; color: #7a4a12; }

.ckb-macros {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s1);
    margin-top: var(--s2);
}

.ckb-macros span {
    padding: 3px var(--s2);
    border-radius: 999px;
    background: #f1e2c4;
    font-size: 11.5px;
    font-weight: 600;
    color: #5c4a2e;
}

/* High Five's room is a fixed 320x200 arena shared by everyone in it, so its
   width and height cannot follow the device the way Timbuktu's viewport does —
   two players with differently shaped rooms would disagree about where the
   walls are. The canvas therefore letterboxes on a tall screen, and the
   surround is painted to match the room's own walls so it reads as a frame
   rather than as the app failing to fill the screen. */
.hf-root {
    background:
        radial-gradient(120% 90% at 50% 45%, #3a2f22 0%, #241d15 70%, #1b150f 100%);
}

/* ---------- living with the notch and the home indicator ---------- */

/* viewport-fit=cover was added so the app could paint edge to edge, and the
   bill for that is arriving here: without these the app bar sits under the
   status bar and the bottom row of every scrolling view sits under the home
   indicator. env() is 0 everywhere else, so none of this shows on a desktop. */
.app-bar {
    padding-top: calc(12px + env(safe-area-inset-top, 0px));
    padding-left: calc(16px + env(safe-area-inset-left, 0px));
    padding-right: calc(16px + env(safe-area-inset-right, 0px));
}

/* Wrath's controls are the only game UI that reaches the bottom edge; the
   other two centre a canvas, which the indicator can safely overlap. */
@media (max-width: 899px) {
    .il-ui { padding-bottom: calc(14px + env(safe-area-inset-bottom, 0px)); }
}

/* The scrolling apps end in a row that would otherwise be half-covered. */
.chx-root,
.ckb-root,
.kge-body {
    padding-bottom: calc(40px + env(safe-area-inset-bottom, 0px));
}

/* Full-bleed games take the side insets in landscape, where the notch is on
   one edge and would otherwise clip the map. */
@media (orientation: landscape) {
    .game-host.full-host {
        padding-left: env(safe-area-inset-left, 0px);
        padding-right: env(safe-area-inset-right, 0px);
        box-sizing: border-box;
    }
}

/* ---------- the strip behind the status bar ---------- */

/* Routed through a variable so it can be given a value in a desktop browser
   to check the layout; on a device it is whatever iOS reports. */
:root { --safe-top: env(safe-area-inset-top, 0px); }

/* Screens with an accent header already paint their own inset. The app picker
   and the sign-in screen have no header, so the strip up there was showing the
   cream page background while every other screen showed orange. This paints it
   for all of them, so the top of the phone is always the header colour. */
body::before {
    content: '';
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: var(--safe-top);
    background: var(--accent);
    z-index: 2000;
    pointer-events: none;
}

/* ...and the headerless screens need to start below it, or their first row
   sits under the clock. */
#picker-screen,
#auth-screen {
    padding-top: var(--safe-top);
    box-sizing: border-box;
}

/* The app bar and CozyHome's header already pad themselves, so they only need
   the variable rather than a second inset. */
.app-bar { padding-top: calc(12px + var(--safe-top)); }

/* The first-person HUD has no business being on top of the pixel town: its
   joystick drove a simulation that is not running, so a phone showed two
   sticks and only one of them did anything. The purse stays — you shop in
   there — but everything that steers or reports on the 3D walk goes. */
.dg-town2d-mode .dg-stick,
.dg-town2d-mode .dg-touch-interact,
.dg-town2d-mode .dg-reticle,
.dg-town2d-mode .dg-prompt,
.dg-town2d-mode .dg-meters,
.dg-town2d-mode .dg-nav,
.dg-town2d-mode .dg-timer,
.dg-town2d-mode .dg-quest-banner {
    display: none !important;
}

/* A road you are under-equipped for. Still pickable — the warning is the
   point, not a wall — so it is marked rather than dimmed into looking
   disabled. */
.tr-route-card.short {
    border-color: rgba(216, 168, 106, 0.5);
}

.tr-rc-warn {
    display: block;
    margin-top: var(--s2);
    padding: var(--s2) var(--s3);
    border-radius: var(--r-sm);
    background: rgba(216, 168, 106, 0.14);
    font-size: var(--t-micro);
    line-height: 1.45;
    color: #e8c08a;
}

/* What you owe the money changer, and how close the qadi is. */
.dg-debt {
    display: flex;
    flex-direction: column;
    gap: var(--s1);
    margin: var(--s3) 0;
    padding: var(--s3);
    border: 1.5px solid rgba(216, 120, 90, 0.45);
    border-radius: var(--r-md);
    background: rgba(216, 120, 90, 0.12);
}

.dg-debt strong { font-size: var(--t-lead); color: #f0b48a; }
.dg-debt span { font-size: var(--t-micro); color: #d9b596; }

/* Standing with the money changers. */
.dg-credit { margin: var(--s3) 0; }

.dg-credit-bar {
    height: 6px;
    border-radius: var(--r-pill);
    background: rgba(255, 255, 255, 0.12);
    overflow: hidden;
}

.dg-credit-fill {
    height: 100%;
    border-radius: var(--r-pill);
    background: linear-gradient(90deg, #c96b4a, #e8c08a);
    transition: width 0.3s ease-out;
}

.dg-credit-row {
    display: flex;
    align-items: baseline;
    gap: var(--s2);
    margin-top: var(--s2);
    flex-wrap: wrap;
}

.dg-credit-row strong { font-size: var(--t-lead); color: #f0d0a0; }
.dg-credit-row span { font-size: var(--t-micro); color: #cbb08a; }

/* A loan above what he will risk on you. */
.dg-item-out { opacity: 0.5; }

/* ---------- Mali: the purse and kit, visible in the pixel town ---------- */

/* .dg-town2d is a sibling of .dg-root with z-index 1, so it painted over the
   whole HUD — the cowry count was being rendered the entire time and simply
   buried. Lifting the HUD is enough; everything else in there is already
   hidden by the town2d rules above. */
.dg-town2d-mode .dg-hud { z-index: 2; }

.dg-hud-right { display: flex; align-items: center; gap: var(--s2); }

/* The HUD is pointer-events: none so it never eats a click meant for the
   desert. The one button in it has to opt back in. */
.dg-inv-btn {
    pointer-events: auto;
    padding: 4px 12px;
    border: 1px solid rgba(255, 240, 210, 0.45);
    border-radius: 999px;
    background: rgba(40, 26, 12, 0.55);
    color: #ffeccc;
    font: inherit;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.02em;
    cursor: pointer;
    backdrop-filter: blur(4px);
}
@media (hover: hover) { .dg-inv-btn:hover { background: rgba(60, 38, 16, 0.75); } }

/* 28px reads right against the purse; a thumb wants 44. The target grows, the
   button does not — same trick as the speaker buttons in KGE. */
.dg-inv-btn { position: relative; }
.dg-inv-btn::after { content: ""; position: absolute; inset: -8px -6px; }

.dg-inv-purse {
    display: flex; flex-direction: column; gap: 2px;
    margin-bottom: var(--s3);
    padding: var(--s2) var(--s3);
    border-radius: 12px;
    background: rgba(0, 0, 0, 0.18);
}
.dg-inv-purse div { display: flex; justify-content: space-between; gap: var(--s3); }
.dg-owe { color: #ff9f7a; }
.dg-unowned { flex: 0 0 auto; font-size: 11px; opacity: 0.6; }
.dg-item-missing { opacity: 0.72; }
.dg-warn-line { margin-top: var(--s2); font-size: 12px; opacity: 0.8; }

/* ---------- Mali: what the run actually made ---------- */

.tr-ledger {
    margin: var(--s3) 0;
    padding: var(--s2) var(--s3);
    border-radius: 12px;
    background: rgba(0, 0, 0, 0.16);
    font-variant-numeric: tabular-nums;
}
.tr-ledger div { display: flex; justify-content: space-between; gap: var(--s3); padding: 2px 0; }
.tr-ledger-sum {
    margin-top: 4px; padding-top: 6px !important;
    border-top: 1px solid rgba(255, 255, 255, 0.18);
    font-size: 1.05em;
}
.tr-pos { color: #8fd694; }
.tr-neg { color: #ff9f7a; }
.tr-burn strong { font-variant-numeric: tabular-nums; opacity: 0.85; }


/* ---------- Mali: type on a phone ----------
 *
 * Deliberately the last block in the file. Several of these classes
 * (.dg-speech, .dg-unowned, .tr-stage-cap small) are defined further down than
 * the media query this used to live in, and at equal specificity the later
 * rule wins — so three of them silently did nothing. Living at the end beats
 * them on order rather than on !important, which would have hidden the problem
 * instead of fixing it.
 */
@media (max-width: 899px) {
    /* This app reads more than any other one here, and it was the only one
       that made its type SMALLER on a phone rather than larger: stop labels
       came out at 9.6px and the meters at 12.5px, on the screen where almost
       all the reading happens. Prose is 15.5px to match a CozyHealth card,
       secondary text no lower than 13, nothing at all under 11.5. */
    /* .dg-card p is what actually governs panel prose — a descendant selector
       at (0,1,1), so it beats a bare .dg-speech no matter which comes last.
       Raising .dg-speech alone changed nothing, silently. */
    .tr-jhead p,
    .tr-card p,
    .tr-trade,
    .dg-card p,
    .dg-speech,
    .dg-hint { font-size: 15.5px; line-height: 1.55; }

    .tr-btn { font-size: 15.5px; }
    .tr-card h3 { font-size: 1.25rem; }
    .tr-head p, .tr-final-sub { font-size: 14.5px; }
    .tr-rc-sum { font-size: 14px; }
    .tr-rc-meta, .tr-rc-reward, .tr-rc-warn { font-size: 13px; }
    .tr-rc-stops { font-size: 12.5px; }
    .tr-log, .tr-stage-cap small, .tr-tip { font-size: 13px; }
    .tr-ledger { font-size: 15px; }

    /* Wider too: 58px cut "Timbuktu" in half, and a truncated place name is
       not a smaller label, it is a different word. */
    .tr-stop b { font-size: 11.5px; max-width: 72px; }

    .dg-item-name, .dg-inv-purse { font-size: 15.5px; }
    .dg-item-note, .dg-warn-line { font-size: 13.5px; }
    .dg-owned, .dg-unowned { font-size: 12.5px; }
    .dg-kicker { font-size: 12px; }
}

/* ---------- Mali: what the town asks of you ---------- */

.dg-favour {
    margin: var(--s3) 0;
    padding: var(--s3);
    border-radius: 12px;
    border: 1px solid rgba(120, 92, 56, 0.3);
    background: rgba(0, 0, 0, 0.05);
}

.dg-favour-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--s3);
    font-weight: 700;
}
.dg-favour-head strong { white-space: nowrap; color: #8a5a20; }

/* The line that makes it a decision rather than a donation: what the purse
   looks like afterwards, said before you commit rather than after. */
.dg-favour-after { margin-top: var(--s2); font-size: 13.5px; color: #6b5636; }
.dg-favour-clock { margin-top: 2px; font-size: 13px; font-style: italic; color: #8a6b3c; }

/* Both choices carry the same visual weight, deliberately. .dg-buy is the
   accent button the shop uses, so leaving "Not this time" with it made
   refusing your own brother look like the recommended action. There is no
   recommended action here — that is the point of asking. */
.dg-favour-btns { display: flex; gap: var(--s2); }
.dg-favour-btns .dg-buy {
    flex: 1 1 0;
    min-height: 46px;
    background: transparent;
    border: 1.5px solid rgba(122, 90, 42, 0.5);
    color: #6b5020;
    font-weight: 700;
}
.dg-favour-yes { border-color: #7a5a2a !important; color: #7a5a2a; }
.dg-favour-yes:disabled { opacity: 0.4; }
@media (hover: hover) {
    .dg-favour-btns .dg-buy:not(:disabled):hover { background: rgba(122, 90, 42, 0.1); }
}

/* ---------- Wrath: the plain of Ilium ---------- */

/* Hidden until a field is mounted, and then it owns the whole box — the duel
   canvas and the move list are both meaningless while you are walking. */
.il-field { display: none; }
.il-field.on { display: block; flex: 1 1 auto; min-height: 0; position: relative; }
.il-root.il-fielding .il-stage,
.il-root.il-fielding .il-ui { display: none; }

.fd-root {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
    background: #1a1208;
    touch-action: none;
    user-select: none;
    -webkit-user-select: none;
}

/* No object-fit: the buffer is resized to the box's own aspect in
   Field._resizeView, so it fills it exactly and the scale is equal in both
   axes. Cover cropped a fixed 320x200 down to about a dozen visible tiles on
   a phone, which is not enough of the plain to steer by. */
.fd-canvas {
    display: block;
    width: 100%;
    height: 100%;
    image-rendering: pixelated;
}

.fd-hud {
    position: absolute;
    top: 0; left: 0; right: 0;
    display: flex;
    justify-content: space-between;
    gap: var(--s3);
    padding: var(--s2) var(--s3);
    font-size: 13px;
    font-weight: 700;
    color: #f6e6c8;
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9);
    pointer-events: none;
}
.fd-favour { color: #ffe08c; }

.fd-banner {
    position: absolute;
    left: 50%;
    bottom: 14%;
    transform: translateX(-50%);
    max-width: min(30ch, 88%);
    padding: var(--s2) var(--s4);
    border-radius: 10px;
    background: rgba(20, 14, 6, 0.82);
    color: #f6e6c8;
    font-size: 14.5px;
    line-height: 1.45;
    text-align: center;
    pointer-events: none;
}
.fd-banner.hidden { display: none; }

.fd-touch.hidden { display: none; }

.fd-stick {
    position: absolute;
    left: 20px;
    bottom: 20px;
    width: 96px;
    height: 96px;
    border-radius: 50%;
    background: rgba(246, 230, 200, 0.12);
    border: 2px solid rgba(246, 230, 200, 0.3);
    touch-action: none;
}

/* Centred by transform, not by a negative margin — see the town stick. */
.fd-stick-nub {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 40px;
    height: 40px;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    background: rgba(246, 230, 200, 0.5);
}

.fd-strike {
    position: absolute;
    right: 22px;
    bottom: 30px;
    width: 74px;
    height: 74px;
    border-radius: 50%;
    border: 2px solid rgba(246, 230, 200, 0.45);
    background: rgba(120, 40, 26, 0.65);
    color: #ffeccc;
    font-size: 28px;
    line-height: 1;
    touch-action: none;
    cursor: pointer;
}
.fd-strike:active { transform: scale(0.94); }

/* ---------- CozyCookBook: describing a recipe ---------- */

.ckb-draft-text {
    width: 100%;
    padding: var(--s3);
    border: 1.5px solid var(--border, #e0cba4);
    border-radius: 12px;
    background: #fffaf0;
    font: inherit;
    line-height: 1.45;
    resize: vertical;
}

.ckb-desc-btn { width: 100%; margin-top: var(--s2); }

/* "or start it empty" — the manual path is still there, just no longer the
   only one, and no longer the one wearing the accent colour. */
.ckb-or {
    display: flex;
    align-items: center;
    gap: var(--s3);
    margin: var(--s4) 0 var(--s3);
    color: #8a7350;
    font-size: 12.5px;
}
.ckb-or::before, .ckb-or::after {
    content: "";
    flex: 1 1 auto;
    height: 1px;
    background: var(--border, #e0cba4);
}

.ckb-draft-title { width: 100%; font-size: 1.05rem; font-weight: 700; }
.ckb-draft-servings { align-items: center; gap: var(--s2); margin: var(--s3) 0; }

.ckb-draft-sec {
    margin: var(--s4) 0 var(--s2);
    font-size: 0.7rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: #8a7350;
}

.ckb-draft-list { display: flex; flex-direction: column; gap: var(--s2); }

/* Name takes the room; amount, unit and the delete stay put. On a phone the
   name gets its own line rather than shrinking to four characters. */
.ckb-draft-ing {
    display: grid;
    grid-template-columns: 1fr 72px 96px 32px;
    grid-template-areas: "name amt unit drop" "match match match match";
    gap: var(--s2);
    align-items: center;
}
.ckb-d-name { grid-area: name; }
.ckb-d-amt  { grid-area: amt; }
.ckb-d-unit { grid-area: unit; }
.ckb-d-match {
    grid-area: match;
    font-size: 11.5px;
    color: #a08a67;
}
.ckb-d-match.ok { color: #5f7a45; }

/* Narrow: the name gets its own line rather than shrinking to four characters,
   and the amount stays a small box — giving it the 1fr made "900" span most of
   the row while the unit had nowhere to go. */
@media (max-width: 560px) {
    .ckb-draft-ing {
        grid-template-columns: 92px 1fr 32px;
        grid-template-areas: "name name name" "amt unit drop" "match match match";
    }
    .ckb-d-unit { width: 100%; }
}

.ckb-draft-step { display: grid; grid-template-columns: 22px 1fr 32px; gap: var(--s2); align-items: start; }
.ckb-d-n { padding-top: 8px; font-size: 12px; font-weight: 700; color: #8a7350; }
.ckb-d-text {
    width: 100%;
    padding: var(--s2);
    border: 1.5px solid var(--border, #e0cba4);
    border-radius: 10px;
    background: #fffaf0;
    font: inherit;
    font-size: 14px;
    line-height: 1.45;
    resize: vertical;
}

.ckb-d-drop {
    grid-area: drop;
    width: 30px; height: 30px;
    border: none; border-radius: 8px;
    background: transparent;
    color: #a08a67;
    font-size: 15px;
    cursor: pointer;
}
.ckb-d-drop:hover { background: rgba(0,0,0,0.06); color: #8a3a2a; }
.ckb-d-add { width: 100%; margin-top: var(--s2); border-style: dashed; }

.ckb-draft-note {
    margin-top: var(--s3);
    padding: var(--s2) var(--s3);
    border-radius: 10px;
    background: rgba(0,0,0,0.05);
    font-size: 13px;
    color: #6b5636;
}
.ckb-draft-error { margin-top: var(--s2); color: #a8432a; font-size: 13.5px; }

/* ---------- CozyHealth: adjusting one plate ---------- */

.chx-adjust-open {
    width: 100%;
    margin-top: var(--s3);
    padding: var(--s2);
    border: 1.5px dashed var(--border, #e0cba4);
    border-radius: 12px;
    background: transparent;
    color: #6b5636;
    font: inherit;
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
}

.chx-adjust {
    margin-top: var(--s3);
    padding: var(--s3);
    border-radius: 12px;
    background: rgba(0, 0, 0, 0.05);
}
.chx-adjust-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--s3);
    margin-bottom: var(--s2);
    font-size: 0.7rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: #8a7350;
}
.chx-adjust-reset {
    border: none; background: none; padding: 0;
    font: inherit; font-size: 11px; letter-spacing: 0.04em;
    color: #8a5a20; text-decoration: underline; cursor: pointer;
}

.chx-adjust-row {
    display: grid;
    grid-template-columns: 1fr 72px 54px 30px;
    gap: var(--s2);
    align-items: center;
    padding: 2px 0;
}
.chx-adjust-name { font-size: 14px; }
.chx-adjust-amt { width: 100%; }
.chx-adjust-unit { font-size: 12.5px; color: #8a7350; }
.chx-adjust-none { grid-column: 2 / 4; font-size: 12px; color: #a08a67; font-style: italic; }
.chx-adjust-drop {
    width: 28px; height: 28px;
    border: none; border-radius: 8px;
    background: transparent; color: #a08a67;
    font-size: 14px; cursor: pointer;
}
.chx-adjust-drop:hover { background: rgba(0,0,0,0.07); color: #8a3a2a; }

/* The line that makes it safe to touch. */
.chx-adjust-foot { margin-top: var(--s2); font-size: 12.5px; }

/* ---------- CozyCookBook: the recipe page stopped being a form ---------- */

.ckb-uncosted { color: #a08a67 !important; font-weight: 500; font-size: 11.5px; }
.ckb-edit-hint { margin-top: var(--s3); font-size: 12.5px; line-height: 1.5; }

/* The match line is a control now: it opens the food picker for that row. */
button.ckb-d-match {
    justify-self: start;
    padding: 2px 8px;
    border: 1px dashed rgba(122, 90, 42, 0.4);
    border-radius: 999px;
    background: transparent;
    font: inherit;
    font-size: 11.5px;
    color: #a08a67;
    text-align: left;
    cursor: pointer;
}
button.ckb-d-match.ok { color: #5f7a45; border-color: rgba(95, 122, 69, 0.45); }
@media (hover: hover) { button.ckb-d-match:hover { background: rgba(0,0,0,0.05); } }

/* The ingredient picker opens over the editor, so it has to sit above it. */
#ckb-sheet { z-index: 70; }

/* ---------- CozyHealth: editing what is already logged ---------- */

/* The row is a button now. It keeps the row's shape rather than looking like
   one, because a list of buttons reads as a menu and this is a list of meals. */
.chx-item-edit { padding: 0; }
.chx-item-open {
    display: flex;
    align-items: center;
    gap: var(--s3);
    flex: 1 1 auto;
    min-width: 0;
    padding: var(--s2) 0 var(--s2) var(--s1);
    border: none;
    background: none;
    font: inherit;
    color: inherit;
    text-align: left;
    cursor: pointer;
}
.chx-item-open .chx-item-main { flex: 1 1 auto; min-width: 0; }
@media (hover: hover) { .chx-item-open:hover { opacity: 0.75; } }

.chx-e-unit { font-size: 14px; color: var(--text-secondary, #8a7350); }
.chx-e-meal { display: flex; flex-wrap: wrap; gap: var(--s2); margin-top: var(--s3); }

/* ---------- CozyHealth: the week behind you ---------- */

.chx-week-head {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--s2);
}
.chx-week-head h3 { margin: 0; }
.chx-week-pick { display: flex; flex-wrap: wrap; gap: var(--s1); }

.chx-week-avg {
    display: flex;
    align-items: baseline;
    gap: var(--s2);
    margin: var(--s2) 0 var(--s3);
}
.chx-week-avg strong { font-size: 1.5rem; font-variant-numeric: tabular-nums; }

.chx-week-chart {
    display: block;
    width: 100%;
    height: 96px;
    overflow: visible;
}
.chx-week-bar { fill: #6fa2b5; }

/* A day with nothing in it is drawn as absent rather than as a zero — they
   mean different things and the average only counts the first kind. */
.chx-week-bar.empty { fill: rgba(120, 92, 56, 0.18); }

.chx-week-avgline {
    stroke: #c8873a;
    stroke-width: 1.5;
    stroke-dasharray: 4 3;
    vector-effect: non-scaling-stroke;
}

.chx-week-days {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    margin-top: 4px;
    font-size: 11.5px;
    text-align: center;
    color: var(--text-secondary, #8a7350);
}
.chx-week-days .empty { opacity: 0.4; }

/* ---------- CozyHealth: the longer view ---------- */

.chx-trend-pick { display: flex; flex-wrap: wrap; gap: var(--s1); margin: var(--s3) 0 var(--s2); }

/* Each chip carries its line's colour in --tc, so the legend and the chart
   cannot disagree about which line is which. */
.chx-tchip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 11px;
    min-height: 34px;
    border: 1.5px solid var(--border, #e0cba4);
    border-radius: 999px;
    background: transparent;
    font: inherit;
    font-size: 12.5px;
    color: var(--text-secondary, #8a7350);
    cursor: pointer;
}
.chx-tchip i {
    width: 9px; height: 9px; border-radius: 50%;
    background: var(--tc);
    opacity: 0.35;
}
.chx-tchip.on {
    border-color: var(--tc);
    color: var(--text-primary, #3a2a18);
    font-weight: 600;
}
.chx-tchip.on i { opacity: 1; }

.chx-trend-chart {
    display: block;
    width: 100%;
    height: 120px;
    margin-top: var(--s1);
    overflow: visible;
}

.chx-trend-legend {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s2) var(--s4);
    margin-top: var(--s2);
    font-size: 12.5px;
    color: var(--text-secondary, #8a7350);
}
.chx-trend-key { display: inline-flex; align-items: baseline; gap: 5px; }
.chx-trend-key i {
    width: 8px; height: 8px; border-radius: 50%;
    align-self: center;
}
.chx-trend-key strong { color: var(--text-primary, #3a2a18); font-variant-numeric: tabular-nums; }
.chx-trend-key small { font-size: 10.5px; opacity: 0.7; }

.chx-trend-note { margin-top: var(--s2); font-size: 12px; line-height: 1.5; }

/* ---------- CozyHealth: several things at once ---------- */

/* Follows you through the search and the portion screens. It is a summary and
   a way back into the list, so it is one control rather than a banner. */
.chx-basket-bar {
    display: flex;
    align-items: center;
    gap: var(--s3);
    width: 100%;
    margin-top: var(--s2);
    padding: var(--s2) var(--s3);
    border: 1.5px solid var(--accent, #f2734d);
    border-radius: 12px;
    background: rgba(242, 115, 77, 0.08);
    font: inherit;
    font-size: 13.5px;
    color: inherit;
    text-align: left;
    cursor: pointer;
}
.chx-basket-bar strong { font-size: 15px; }
.chx-basket-kcal { margin-left: auto; font-variant-numeric: tabular-nums; opacity: 0.8; }
.chx-basket-go { font-weight: 700; color: var(--accent, #f2734d); white-space: nowrap; }
.chx-basket-tab { margin: 0 0 var(--s2); }

/* Three buttons will not fit side by side on a narrow phone, so the middle one
   takes its own line rather than all three shrinking to initials. */
.chx-foot-3 { flex-wrap: wrap; }
.chx-btn-plus { flex: 1 1 100%; order: -1; }
@media (min-width: 560px) {
    .chx-btn-plus { flex: 0 1 auto; order: 0; }
}

.chx-basket-list { display: flex; flex-direction: column; gap: var(--s1); margin: var(--s3) 0; }
.chx-basket-row {
    display: flex;
    align-items: center;
    gap: var(--s2);
    padding: var(--s2) 0;
    border-bottom: 1px solid rgba(120, 92, 56, 0.14);
}
.chx-basket-name { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; font-size: 14px; }
.chx-basket-name small { font-size: 11.5px; opacity: 0.7; }
.chx-basket-num { font-variant-numeric: tabular-nums; font-size: 13px; white-space: nowrap; }
.chx-basket-drop {
    width: 28px; height: 28px; flex: 0 0 auto;
    border: none; border-radius: 8px; background: transparent;
    color: #a08a67; font-size: 14px; cursor: pointer;
}
.chx-basket-drop:hover { background: rgba(0,0,0,0.07); color: #8a3a2a; }

.chx-basket-label {
    display: block;
    margin-top: var(--s3);
    font-size: 0.7rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-secondary, #8a7350);
}

/* A logged sitting, in the day's list. */
.chx-group {
    margin: var(--s2) 0;
    padding-left: var(--s3);
    border-left: 3px solid rgba(242, 115, 77, 0.35);
}
.chx-group-head {
    display: flex;
    align-items: baseline;
    gap: var(--s2);
    padding: var(--s1) 0;
}
.chx-group-head strong { font-size: 15.5px; }
.chx-group-head .chx-item-num { margin-left: auto; }

/* The foods sit in under the name they were logged as. Without the indent the
   sitting's name and its contents share one offset and read as five peers
   rather than one thing containing four.
 *
 * Both selectors are needed: .chx-item-edit sets `padding: 0` as a shorthand,
 * which would otherwise wipe the padding-left back off again. Two classes beat
 * one, so this wins on specificity rather than on order. */
.chx-group .chx-item,
.chx-group .chx-item-edit { padding-left: var(--s4); }

/* The row-as-button carries its own left padding, and doubling up would step
   the food in twice as far as intended. */
.chx-group .chx-item-open { padding-left: 0; }

/* ---------- CozyHealth: when you ate it ---------- */

.chx-when-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s3);
    margin-top: var(--s3);
    font-size: 14px;
}
.chx-when-row span { color: var(--text-secondary, #8a7350); }

/* Safari renders a bare time input with no border and no height worth tapping,
   so it is styled like the other fields rather than left to the platform. */
.chx-when-row input[type="time"] {
    min-height: 42px;
    padding: var(--s2) var(--s3);
    border: 1.5px solid var(--border, #e0cba4);
    border-radius: 10px;
    background: #fff;
    font: inherit;
    font-size: 15px;
    font-variant-numeric: tabular-nums;
}

/* ---------- painted event scenes ----------
 * Sits above the words on an event card, never instead of them: an event with
 * no art removes the element and the card reads exactly as it did before. */
.tr-event-art {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 10px;
    margin-bottom: var(--s3);
    image-rendering: pixelated;      /* pixel art, never smoothed on the way up */
}

/* ---------- the face before the duel ----------
 * Sits above the name on the prelude panel. A foe with no portrait removes the
 * element and the panel reads exactly as it did — the words carry the scene,
 * the picture only introduces it. */
.il-pre-face {
    display: block;
    width: 96px;
    height: 96px;
    margin: 0 auto var(--s2);
    image-rendering: pixelated;      /* pixel art, never smoothed on the way up */
}
