/* ══════════════════════════════════════════════════════════════════════
   Värkappen / TimeItBaby — "Organic" design system
   Warm cream ground, terracotta accent, sage second voice, Caprasimo
   display over Figtree body, over-rounded containers and pill buttons.
   Tokens below are the single source of truth; component .razor.css files
   consume them and must not hard-code hexes.
   ══════════════════════════════════════════════════════════════════════ */

/* ── Fonts (self-hosted: a CDN is unreachable for an offline PWA) ────── */
@font-face {
    font-family: 'Caprasimo';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('../fonts/caprasimo-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Caprasimo';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('../fonts/caprasimo-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Figtree ships as a variable font — one file covers the whole 300–900 range. */
@font-face {
    font-family: 'Figtree';
    font-style: normal;
    font-weight: 300 900;
    font-display: swap;
    src: url('../fonts/figtree-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Figtree';
    font-style: normal;
    font-weight: 300 900;
    font-display: swap;
    src: url('../fonts/figtree-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ── Design tokens ─────────────────────────────────────────────────── */
:root {
    /* Ground & surfaces */
    --bg:            #f5ead8;  /* the warm page ground */
    --bg-deep:       #e7ddcb;  /* one step darker — the desktop matte */
    --surface:       #f9f4ed;  /* neutral-100 — cards sit on the ground */
    --surface-2:     #eee7db;  /* neutral-200 — tracks, inert chips */
    --card-bg:       #f9f4ed;  /* legacy alias used by page CSS */
    --line:          #eee7db;
    --line-strong:   #dcd3c4;  /* neutral-300 — dashed borders, rules */

    /* Ink */
    --text:          #201e1d;
    --text-muted:    #645c50;  /* neutral-700 — body-size secondary copy */
    --text-faint:    #82796a;  /* neutral-600 — kickers, meta */
    --text-ghost:    #a19786;  /* neutral-500 — inactive tabs */

    /* Terracotta ramp — the primary accent */
    --accent-100:    #fff2eb;
    --accent-light:  #ffe1d0;  /* accent-200 */
    --accent-300:    #ffc6a5;
    --accent-400:    #f6a06b;
    --accent-500:    #d67f48;
    --accent:        #c67139;  /* the base */
    --accent-deep:   #b2622d;  /* accent-600 — pressed */
    --accent-dark:   #8c491a;  /* accent-700 — accent-size text on cream */
    --accent-900:    #402310;

    /* Sage ramp — the second voice */
    --sage-100:      #f0fae1;
    --sage-200:      #e1eecc;
    --sage-300:      #ccdbb2;
    --sage-400:      #aebf92;
    --sage:          #7a8a5e;
    --sage-700:      #56633f;
    --sage-800:      #3d472b;

    /* Type */
    --font-heading:  'Caprasimo', Georgia, 'Times New Roman', serif;
    /* The emoji faces are part of the stack, not an afterthought: flags in the
       language picker and the hospital-bag category marks have no glyphs in
       Figtree and would otherwise fall back to a tofu box. */
    --font-emoji:    'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', 'Segoe UI Symbol';
    --font-body:     'Figtree', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif,
                     'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji';

    /* Shape — over-round; pills are literally 999px */
    --radius:        28px;
    --radius-md:     16px;
    --radius-sm:     8px;
    --radius-pill:   999px;

    /* Elevation — soft, ink-tinted, tuned to the cream ground */
    --shadow-sm:     0 1px 2px rgba(46,43,37,.14);
    --shadow-md:     0 3px 10px rgba(46,43,37,.16);
    --shadow-lg:     0 12px 32px rgba(46,43,37,.22);

    --bar-h:         3.25rem;  /* shared height for header & bottom tab bar */
}

/* ── Base ───────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

html {
    font-family: var(--font-body);
    font-size: 16px; /* never below 16px — prevents iOS auto-zoom */
    background-color: var(--bg);
    color: var(--text);
    margin: 0;
    padding: 0;
    height: 100%;
    -webkit-text-size-adjust: 100%;
    overscroll-behavior: none;
}

/* Scrollbars are part of the palette, not chrome we can ignore. A browser-default track
   is white, which on this warm ground reads as a bright stripe rather than as part of the
   page. Browsers with overlay scrollbars (Safari, most touch devices) ignore all of this.

   The two scrollbars sit on different grounds and so take different tracks: the window
   scrollbar runs down the desktop matte (--bg-deep), while the inner .app-content pane
   below the breakpoint runs down the app surface (--bg). */
html          { scrollbar-color: var(--sage) var(--bg-deep); }  /* thumb, track */
.app-content  { scrollbar-color: var(--sage) var(--bg); }

/* Older Chromium and Safari-with-classic-scrollbars need the -webkit- pseudo-elements. */
html::-webkit-scrollbar,
.app-content::-webkit-scrollbar { width: 12px; }

html::-webkit-scrollbar-track          { background: var(--bg-deep); }
.app-content::-webkit-scrollbar-track  { background: var(--bg); }

html::-webkit-scrollbar-thumb,
.app-content::-webkit-scrollbar-thumb {
    background: var(--sage);
    border-radius: var(--radius-pill);
}

/* The thumb's inset border must match whatever it sits on, so it reads as a pill
   floating on the track rather than a bar filling it. */
html::-webkit-scrollbar-thumb         { border: 3px solid var(--bg-deep); }
.app-content::-webkit-scrollbar-thumb { border: 3px solid var(--bg); }

body {
    font-family: inherit;
    font-size: inherit;
    line-height: 1.55;
    background: transparent;
    color: var(--text);
    margin: 0;
    padding: 0;
    height: 100%;
    -webkit-text-size-adjust: 100%;
    overscroll-behavior: none;
}

/* On mobile: lock body position so iOS can't scroll/bounce the page itself.
   The scrollable content lives inside .app-content which handles its own scroll. */
@media (max-width: 820px) {
    body {
        position: fixed;
        width: 100%;
        overflow: hidden;
    }
}

#app { height: 100%; }

h1, h2, h3, h4, h5 {
    font-family: var(--font-heading);
    font-weight: 400;
    line-height: 1.12;
    letter-spacing: -0.015em;
}

h1:focus { outline: none; }

a { color: var(--accent-dark); text-underline-offset: 3px; }
a:hover { color: var(--accent-900); }

.btn-link { color: var(--accent-dark); }

::selection { background: var(--accent-light); }

/* Themed keyboard focus everywhere — never the default blue ring. */
:focus { outline: none; }
:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* ── Bootstrap overrides ────────────────────────────────────────────── */
/* Bootstrap 5.3 drives every button state off --bs-btn-* custom properties, and
   its state rules (.btn:disabled, .btn:hover, …) outrank a bare .btn-danger
   declaration. Retheming therefore means setting the variables, not the
   properties — otherwise the disabled and hover states stay Bootstrap blue/red. */
.btn {
    font-family: var(--font-body);
    font-weight: 700;
    border-radius: var(--radius-pill);
    padding: 0.6rem 1.25rem;
    transition: background-color .15s, color .15s, border-color .15s;
}

.btn-primary {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--accent);
    --bs-btn-border-color: var(--accent);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--accent-deep);
    --bs-btn-hover-border-color: var(--accent-deep);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: var(--accent-dark);
    --bs-btn-active-border-color: var(--accent-dark);
    --bs-btn-disabled-color: #fff;
    --bs-btn-disabled-bg: var(--accent);
    --bs-btn-disabled-border-color: var(--accent);
}

.btn-secondary {
    --bs-btn-color: var(--text-muted);
    --bs-btn-bg: transparent;
    --bs-btn-border-color: var(--line-strong);
    --bs-btn-hover-color: var(--text);
    --bs-btn-hover-bg: var(--surface-2);
    --bs-btn-hover-border-color: var(--line-strong);
    --bs-btn-active-color: var(--text);
    --bs-btn-active-bg: var(--surface-2);
    --bs-btn-active-border-color: var(--line-strong);
    --bs-btn-disabled-color: var(--text-ghost);
    --bs-btn-disabled-bg: transparent;
    --bs-btn-disabled-border-color: var(--line-strong);
    border-width: 2px;
}

/* Destructive actions read as the deepest terracotta rather than a foreign red —
   the palette already carries enough weight at accent-700 to signal caution. */
.btn-danger {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--accent-dark);
    --bs-btn-border-color: var(--accent-dark);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--accent-900);
    --bs-btn-hover-border-color: var(--accent-900);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: var(--accent-900);
    --bs-btn-active-border-color: var(--accent-900);
    --bs-btn-disabled-color: #fff;
    --bs-btn-disabled-bg: var(--accent-dark);
    --bs-btn-disabled-border-color: var(--accent-dark);
}

.btn:focus, .btn:active:focus, .form-control:focus {
    box-shadow: 0 0 0 3px var(--accent-light);
}

.form-control, .form-select {
    border-radius: var(--radius-md);
    border-color: var(--line-strong);
    background-color: var(--surface);
    color: var(--text);
    font-family: var(--font-body);
}
.form-control:focus { border-color: var(--accent); }

.content { padding-top: 1rem; }

.valid.modified:not([type=checkbox]) { outline: 1px solid var(--sage); }
.invalid { outline: 1px solid var(--accent-dark); }
.validation-message { color: var(--accent-dark); }

/* ── Blazor chrome ──────────────────────────────────────────────────── */
#blazor-error-ui {
    color-scheme: light only;
    background: var(--accent-light);
    color: var(--accent-900);
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(46,43,37,.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

.blazor-error-boundary {
    background: var(--accent-dark);
    border-radius: var(--radius-md);
    padding: 1rem 1.25rem;
    color: #fff;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.loading-progress {
    position: absolute;
    display: block;
    width: 8rem;
    height: 8rem;
    inset: 20vh 0 auto 0;
    margin: 0 auto 0 auto;
}

    .loading-progress circle {
        fill: none;
        stroke: var(--surface-2);
        stroke-width: 0.6rem;
        transform-origin: 50% 50%;
        transform: rotate(-90deg);
    }

        .loading-progress circle:last-child {
            stroke: var(--accent);
            stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
            transition: stroke-dasharray 0.05s ease-in-out;
        }

.loading-progress-text {
    position: absolute;
    text-align: center;
    font-family: var(--font-heading);
    color: var(--accent-dark);
    inset: calc(20vh + 3.25rem) 0 auto 0.2rem;
}

    .loading-progress-text:after {
        content: var(--blazor-load-percentage-text, "Loading");
    }

code { color: var(--accent-dark); }

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--text-faint);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* ── Wide screen: centre the app frame like a tablet ─────────────── */
/* Trigger just above iPad (820px) so a real iPad still fills edge-to-edge */
@media (min-width: 821px) {
    html {
        background-color: var(--bg-deep);

        /* Reserve the scrollbar gutter on BOTH edges so the content box stays symmetric
           inside the window. Without this, #app's auto margins centre it in the content
           box — which excludes the scrollbar — leaving the frame sitting half a
           scrollbar-width left of the true centre on any browser with classic
           (space-taking) scrollbars. Browsers with overlay scrollbars reserve nothing,
           so this is a no-op for them. */
        scrollbar-gutter: stable both-edges;
    }

    /* Desktop scrolls the WINDOW, not an inner pane.
       The mobile shell deliberately locks the body and scrolls .app-content instead —
       that is what stops iOS rubber-banding the whole page in the installed PWA, and it
       must stay exactly as it is below 821px. On a desktop browser the same trick is
       actively wrong: it removes the window scrollbar, buries a replacement one ~140px
       inside the right-hand edge of the frame, and leaves the wheel dead everywhere
       outside the 820px column. So above the breakpoint we hand scrolling back to the
       browser. See the matching block in Layout/MainLayout.razor.css. */
    body {
        background: transparent;
        height: auto;
        overflow: visible;
    }

    #app {
        /* 820px is a cap, not a fixed size. Above the breakpoint the min() resolves to
           820px every time (the body is always wider), so this reads the same as the old
           flat value there — the difference is that it can no longer exceed its container
           if the body ever gains padding or a narrower parent. The genuine adaptation to
           screen size happens at the breakpoint itself: full-bleed below, capped above. */
        width: min(820px, 100%);
        margin-inline: auto;   /* centring comes from auto margins now, not body flex */
        height: auto;          /* override the global #app { height: 100% } */
        min-height: 100vh;     /* short pages still fill the window */
        background: var(--bg);
        box-shadow: var(--shadow-lg);
    }

    /* Keep Blazor error banner within the app frame */
    #blazor-error-ui {
        max-width: 820px;
        left: 50%;
        transform: translateX(-50%);
    }
}
