/* Loaded first, after WebClientBase's app-base.css (which holds .font-display, .animate-* and .btn-glossy).
   The design tokens, the app-like behaviour on phones, the phone-width column, the phone frame and the shell.
   index.html loads the stylesheets in a fixed order (Game/docs/ui-style.md, "Stylesheets"). */

/* ---------------------------------------------------------------------------
   The design tokens.
   The token names differ from the ThemeColors names (--bg-*, --text-*, --border-color) that App.razor
   declares after this stylesheet, so neither overrides the other.
   --------------------------------------------------------------------------- */
:root {
    /* --- Ground and surfaces. --ground is the page background, --ground-pool the lighter area above it, and
       --surface and --surface-deep the two stops of the panel and card gradient. --- */
    --ground:          #061711;
    --ground-pool:     #0e2b22;
    --surface:         #0e1b16;
    --surface-deep:    #060f0c;
    --surface-lift:    #13291f;   /* hover state and raised plates */

    /* --- Gold. Used only for attention and rewards, not for decoration. --- */
    --gold:            #f5c542;
    --gold-light:      #ffe9a8;
    --gold-deep:       #b8801a;
    --gold-glow:       rgba(245, 197, 66, 0.55);
    --on-gold:         #2a1f08;   /* text on a gold fill */

    /* --- Text colours. --- */
    --ink:             #f2efe6;
    --ink-2:           #b9c2b6;
    --ink-3:           #8a948a;

    /* --- Lines and scrims. Two neutral hairlines, one gilt line, and the scrims behind a dialog. --- */
    --hairline:        rgba(255, 255, 255, 0.08);
    --hairline-strong: rgba(255, 255, 255, 0.16);
    --line-gilt:       rgba(240, 214, 147, 0.35);
    --scrim:           rgba(2, 8, 6, 0.55);   /* the .pnl backdrop */
    --scrim-deep:      rgba(2, 8, 6, 0.92);

    /* --- Meaning accents: claimable, time-limited, informational and danger. Use them only to carry that
       meaning, never as decoration. A border is gilt or hairline, never an accent. --- */
    --claim:           #2ee6c5;
    --live:            #e879f9;
    --progress:        #60a5fa;
    --danger:          #fb7185;
    /* Light variants of the accents, used for flashes, the same way --gold-light relates to --gold.
       --claim-light is currently unused. */
    --claim-light:     #99f6e4;
    --live-light:      #f0abfc;
    --progress-light:  #bae6fd;

    /* --- Type. Lilita One for headings, numbers and buttons, Nunito for body text. Both are self-hosted under
       wwwroot/fonts (SIL Open Font License), because the game loads no font from Google. Lilita One has one weight,
       so a rule that uses it sets font-weight: 400 and the browser draws no synthetic bold. --- */
    --font-display:    'Lilita One', 'Nunito', system-ui, sans-serif;
    --font-body:       'Nunito', system-ui, sans-serif;

    /* --- Corner radii. --- */
    --r-strip:         0.2rem;
    --r-key:           0.3rem;
    --r-panel:         0.6rem;
    --r-card:          0.9rem;
    --r-pill:          999px;

    /* --- Shadows and the panel gradient. --- */
    --shadow-panel:      0 24px 60px rgba(0, 0, 0, 0.75);
    --grad-panel:      linear-gradient(180deg, var(--surface), var(--surface-deep));

    /* --- Motion. Use these durations and this easing instead of new values. --ease-spring is in
       app-base.css. --- */
    --t-fast:          0.12s;
    --t:               0.22s;
    --t-slow:          0.42s;
    --ease:            cubic-bezier(0.32, 0.72, 0, 1);

    /* --- Feedback: hover lift, press scale, hover glow, and the opacity of a disabled control. --- */
    --press-scale:      0.97;
    --hover-lift:       -1px;
    --hover-glow:       0 0 0 1px rgba(255, 255, 255, 0.12);
    --disabled-opacity: 0.45;

    /* --- Spacing and chrome heights. --- */
    --gap:             0.75rem;
    --pad:             1rem;
    --col:             27rem;
    --hud-h:           3rem;
    --nav-h:           4.25rem;

    /* --- The bottom safe area the app keeps clear. Every bottom inset reads this instead of env() directly.

       It is capped below the full inset. iOS reports a bottom inset for the home indicator that is sized for
       a native tab bar including its own bottom padding. The app's bars already have that padding, so the
       full inset would add an empty band under them in the installed web app. The cap still clears the
       home indicator.

       The top inset is used in full (env(safe-area-inset-top)), because the status bar occupies all of
       it. --- */
    --safe-b:          min(env(safe-area-inset-bottom), 1.25rem);
}

/* ---------------------------------------------------------------------------
   The fonts (Game/docs/ui-style.md, "Font"). The files come from the npm packages @fontsource/lilita-one 5.2.8 and
   @fontsource-variable/nunito 5.3.0; the licences are next to them. The unicode ranges are the packages' own: the
   latin file holds every letter the five themes' text uses, and the browser loads the latin-ext file only for a
   letter outside it.
   --------------------------------------------------------------------------- */
@font-face {
    font-family: 'Lilita One';
    font-style: normal;
    font-display: swap;
    font-weight: 400;
    src: url(../fonts/lilita-one-latin-400-normal.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: 'Lilita One';
    font-style: normal;
    font-display: swap;
    font-weight: 400;
    src: url(../fonts/lilita-one-latin-ext-400-normal.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;
}

@font-face {
    font-family: 'Nunito';
    font-style: normal;
    font-display: swap;
    font-weight: 200 1000;
    src: url(../fonts/nunito-latin-wght-normal.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: 'Nunito';
    font-style: normal;
    font-display: swap;
    font-weight: 200 1000;
    src: url(../fonts/nunito-latin-ext-wght-normal.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;
}

/* ---------------------------------------------------------------------------
   The casual-game UI tokens (Game/docs/ui-style.md, "Tokens"). The components in components.css read only these
   --ui-* properties. :root holds the default set, which is the football set; each theme's set below replaces it on
   every element with that theme's data-theme attribute (the shell, a picker card, the boot screen).
   Each colour ramp has three stops: -light is the top of a button's gradient, the plain name its middle, and -dark
   its bottom edge.
   --------------------------------------------------------------------------- */
:root {
    --ui-font-display:     var(--font-display);
    --ui-outline:          #0a1a10;   /* the dark outline of buttons, pills, panels and stroked text */
    --ui-shadow:           rgba(0, 0, 0, 0.35);

    --ui-primary-light:    #ffe27a;   /* the main action: Spin, Claim, Buy */
    --ui-primary:          #f7b928;
    --ui-primary-dark:     #b9740b;
    --ui-on-primary:       #ffffff;

    --ui-secondary-light:  #8be38f;   /* the second action: Build, Add friends */
    --ui-secondary:        #3aa655;
    --ui-secondary-dark:   #1d6b31;
    --ui-on-secondary:     #ffffff;

    --ui-danger-light:     #ff9b85;   /* attacks */
    --ui-danger:           #ee4b3b;
    --ui-danger-dark:      #a3241a;
    --ui-on-danger:        #ffffff;

    --ui-plus-light:       #a8ef6e;   /* the + on a currency pill */
    --ui-plus:             #4fc22c;
    --ui-plus-dark:        #2a7d15;

    --ui-badge:            #ff3b30;   /* the count badge on a nav button */
    --ui-on-badge:         #ffffff;

    --ui-panel-light:      #24603b;   /* a framed card */
    --ui-panel:            #1a4a2d;
    --ui-panel-border:     #e9b949;
    --ui-panel-ink:        #ffffff;
    --ui-panel-ink-2:      #d4ead9;

    --ui-ribbon-light:     #ff7d6b;
    --ui-ribbon:           #e2463b;
    --ui-ribbon-dark:      #9c2219;

    --ui-pill-bg:          rgba(4, 18, 10, 0.62);   /* a currency pill */
    --ui-pill-ink:         #ffffff;
    --ui-pill-ink-2:       #cfe3d4;
    --ui-pill-stroke:      var(--ui-outline);
    --ui-pill-rim:         rgba(255, 255, 255, 0.22);   /* the light inner rim that lifts a dark pill off a dark ground */

    --ui-nav-light:        #2b6a42;   /* the bottom navigation bar */
    --ui-nav:              #174429;
    --ui-nav-ink:          #ffffff;
    --ui-nav-active:       #ffe27a;

    --ui-bubble:           #ffffff;   /* a tooltip */
    --ui-bubble-ink:       #16241b;
    --ui-pointer:          #f7b928;   /* the guide's bouncing arrow */

    /* Shapes and motion of the components. */
    --ui-radius-button:    0.95rem;
    --ui-radius-panel:     1.15rem;
    --ui-border:           2.5px;
    --ui-edge:             4px;       /* the thick darker bottom edge of a button */
    --ui-press:            3px;       /* how far a button moves down when pressed */
    --ui-pop:              cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* Lilita One has one weight, so the browser draws no synthetic bold for it. */
html { font-synthesis-weight: none; }

[data-theme="putki"] {
    --ui-outline:          #0b1424;
    --ui-primary-light:    #8fc6ff;
    --ui-primary:          #2f7ee8;
    --ui-primary-dark:     #164b9c;
    --ui-on-primary:       #ffffff;
    --ui-secondary-light:  #ffffff;
    --ui-secondary:        #e6edf5;
    --ui-secondary-dark:   #9aa9bb;
    --ui-on-secondary:     #1c2a3c;
    --ui-panel-light:      #33455c;
    --ui-panel:            #263547;
    --ui-panel-border:     #8fc6ff;
    --ui-panel-ink:        #ffffff;
    --ui-panel-ink-2:      #d2deec;
    --ui-ribbon-light:     #6fb2ff;
    --ui-ribbon:           #2f7ee8;
    --ui-ribbon-dark:      #164b9c;
    --ui-pill-bg:          rgba(6, 12, 22, 0.62);
    --ui-pill-ink-2:       #cbd8e8;
    --ui-nav-light:        #3a4d66;
    --ui-nav:              #223246;
    --ui-nav-active:       #8fc6ff;
    --ui-bubble-ink:       #1c2430;
    --ui-pointer:          #2f7ee8;
}

[data-theme="cats"] {
    --ui-outline:          #5a2c14;
    --ui-primary-light:    #ffc98a;
    --ui-primary:          #ff8f3a;
    --ui-primary-dark:     #c15a14;
    --ui-on-primary:       #ffffff;
    --ui-secondary-light:  #ffd2de;
    --ui-secondary:        #f58fac;
    --ui-secondary-dark:   #c25475;
    --ui-on-secondary:     #ffffff;
    --ui-panel-light:      #fffaf3;
    --ui-panel:            #ffeedd;
    --ui-panel-border:     #ff8f3a;
    --ui-panel-ink:        #3b2a2f;
    --ui-panel-ink-2:      #5e4650;
    --ui-ribbon-light:     #ffa36b;
    --ui-ribbon:           #f2703a;
    --ui-ribbon-dark:      #a8441a;
    --ui-pill-bg:          rgba(255, 255, 255, 0.92);
    --ui-pill-ink:         #3b2a2f;
    --ui-pill-ink-2:       #6b4f5a;
    --ui-pill-stroke:      transparent;
    --ui-pill-rim:         rgba(255, 143, 58, 0.35);
    --ui-nav-light:        #ffb877;
    --ui-nav:              #f28a3c;
    --ui-nav-ink:          #ffffff;
    --ui-nav-active:       #fff3c4;
    --ui-bubble-ink:       #3b2a2f;
    --ui-pointer:          #ff8f3a;
}

[data-theme="allotment"] {
    --ui-outline:          #2e2112;
    --ui-primary-light:    #bfe88a;
    --ui-primary:          #6fb43f;
    --ui-primary-dark:     #3d7a1f;
    --ui-on-primary:       #ffffff;
    --ui-secondary-light:  #e0b07c;
    --ui-secondary:        #b47a46;
    --ui-secondary-dark:   #774a24;
    --ui-on-secondary:     #ffffff;
    --ui-panel-light:      #fffbf0;
    --ui-panel:            #f3e8cd;
    --ui-panel-border:     #8b6a44;
    --ui-panel-ink:        #3a2b1e;
    --ui-panel-ink-2:      #5a4632;
    --ui-ribbon-light:     #e98d5f;
    --ui-ribbon:           #c8603a;
    --ui-ribbon-dark:      #873a1d;
    --ui-pill-bg:          rgba(255, 252, 242, 0.94);
    --ui-pill-ink:         #3a2b1e;
    --ui-pill-ink-2:       #5f4b37;
    --ui-pill-stroke:      transparent;
    --ui-pill-rim:         rgba(139, 106, 68, 0.3);
    --ui-nav-light:        #a27b4f;
    --ui-nav:              #7a5733;
    --ui-nav-ink:          #ffffff;
    --ui-nav-active:       #d9f3a8;
    --ui-bubble-ink:       #3a2b1e;
    --ui-pointer:          #6fb43f;
}

[data-theme="space"] {
    --ui-outline:          #02081a;
    --ui-primary-light:    #9ff8ff;
    --ui-primary:          #1fcde0;
    --ui-primary-dark:     #0a7d96;
    --ui-on-primary:       #ffffff;
    --ui-secondary-light:  #a9a2ff;
    --ui-secondary:        #6a5cff;
    --ui-secondary-dark:   #3a2db8;
    --ui-on-secondary:     #ffffff;
    --ui-panel-light:      #17306a;
    --ui-panel:            #0e2150;
    --ui-panel-border:     #22e5f5;
    --ui-panel-ink:        #ffffff;
    --ui-panel-ink-2:      #c3dbf2;
    --ui-ribbon-light:     #a08bff;
    --ui-ribbon:           #6a4dff;
    --ui-ribbon-dark:      #3a22a8;
    --ui-pill-bg:          rgba(2, 8, 26, 0.66);
    --ui-pill-rim:         rgba(34, 229, 245, 0.35);
    --ui-pill-ink-2:       #bcd3ee;
    --ui-nav-light:        #1b3772;
    --ui-nav:              #0c1d48;
    --ui-nav-active:       #9ff8ff;
    --ui-bubble-ink:       #06122e;
    --ui-pointer:          #1fcde0;
}

/* In a browser tab, iOS Safari ends the page above its own toolbar, which already clears the home indicator, but
   still reports a bottom inset. Reserving it would leave an empty band between the navigation and the toolbar. */
@media not all and (display-mode: standalone) {
    :root {
        --safe-b: 0px;
    }
}

/* ---------------------------------------------------------------------------
   App-like behaviour on phones and in the desktop phone frame
   - The page never scrolls or zooms.
   - No pull-to-refresh or overscroll bounce.
   - No double-tap zoom and no long-press selection menus.

   Text is not selectable except inside form controls and the Home screen's facts (.rj-home__facts dd), so a
   long press on a control does not open a selection menu.
   --------------------------------------------------------------------------- */
html,
body {
    height: 100%;
    margin: 0;
    overflow: hidden;                 /* the document never scrolls */
    overscroll-behavior: none;        /* no pull-to-refresh or overscroll bounce */
    touch-action: manipulation;       /* no double-tap zoom */
    -webkit-user-select: none;
    user-select: none;                /* no long-press text selection menus */
    -webkit-touch-callout: none;      /* no iOS long-press Copy/Share/Save menu */
    -webkit-tap-highlight-color: transparent;
}

/* Block image dragging and drag-to-save. */
img {
    -webkit-user-drag: none;
    user-drag: none;
}

/* Fix the body in place so mobile Safari cannot drag the whole page. */
body {
    position: fixed;
    inset: 0;
}

/* Text in form controls stays selectable. */
button,
input,
textarea,
select {
    -webkit-user-select: auto;
    user-select: auto;
}

/* ---------------------------------------------------------------------------
   Phone-width column
   Limits the UI to a phone-width column, centred on a desktop window.
   --------------------------------------------------------------------------- */
.mp-column {
    max-width: 26rem;
}

/* #app is the app's screen, and on a large enough window it becomes the phone frame below. Lengths inside
   the app use percentages and container units instead of viewport units, because on a desktop `vw` measures
   the browser window, not the frame.

   `container-type: inline-size` makes `cqw` a hundredth of the app's width, both on a phone and inside the
   frame. */
#app {
    height: 100%;
    container-type: inline-size;
}

/* <main> is the only scroll surface, and scrolls only when a view is taller than the screen. The
   transparent top bar is drawn over the top of it. */
main {
    height: 100%;
    overflow-y: auto;
    overscroll-behavior: contain;
    /* Keep clear of the bottom safe area. */
    padding-bottom: calc(1.25rem + var(--safe-b));
}

/* No element inside the app draws a scrollbar, because a phone has none. The rule applies to every
   element, so a scroll surface added later also hides its scrollbar. The surfaces still scroll by wheel,
   keyboard and touch. With no scrollbar, `clientWidth` is the full width of the
   surface on every platform. */
#app,
#app * {
    scrollbar-width: none;          /* Firefox */
    -ms-overflow-style: none;       /* legacy Edge */
}

#app::-webkit-scrollbar,
#app *::-webkit-scrollbar {
    display: none;                  /* Chromium, Safari */
}

/* ---------------------------------------------------------------------------
   The phone frame
   On a window large enough to hold it, the app is drawn in an iPhone-sized box in the middle of the window.
   On a smaller window, such as a phone, the app fills the window. The frame has a transform, which makes it
   the containing block for every `position: fixed` element inside it, so dialogs and the connection shell are
   positioned against the frame, not the window.
   --------------------------------------------------------------------------- */
@media (min-width: 34rem) and (min-height: 40rem) {
    body {
        display: flex;
        align-items: center;
        justify-content: center;
        /* The background around the frame, darker than anything inside it so the frame's edge stands out. */
        background:
            radial-gradient(ellipse 70% 60% at 50% 40%, #10161d 0%, #05080b 70%),
            #05080b;
    }

    #app {
        position: relative;
        /* content-box, so the border is the bezel around the screen and not part of it. */
        box-sizing: content-box;
        width: 390px;
        max-width: calc(100vw - 3.5rem);
        /* The iPhone screen height when the window has room, otherwise as much as fits. */
        height: min(844px, calc(100dvh - 4rem));
        border: 11px solid #23272f;
        border-radius: 3rem;
        overflow: hidden;
        transform: translateZ(0);
        /* A light hairline outside the bezel, a darker seam between the screen and the bezel, and the
           frame's drop shadow. */
        box-shadow:
            0 0 0 1px rgba(255, 255, 255, 0.14),
            0 0 0 12px rgba(0, 0, 0, 0.35),
            0 0 0 1px rgba(0, 0, 0, 0.9) inset,
            0 34px 80px -14px rgba(0, 0, 0, 0.9);
    }
}

/* A tablet-sized window gets the same portrait layout at a larger size. The app is laid out in `rem`, so
   raising the root font size scales the text, the spacing, the chrome and the frame together.

   The query requires height as well as width, so a portrait tablet matches and a wide desktop monitor does
   not. `rem` in a media query is always the initial 16px, so changing the root font size does not affect
   the query. */
@media (min-width: 32rem) and (min-height: 64rem) {
    :root { font-size: 18px; }

    #app {
        width: 439px;
        height: min(950px, calc(100dvh - 4rem));
    }
}

/* ---------------------------------------------------------------------------
   The shell and the Home screen
   --------------------------------------------------------------------------- */
/* The shell sets the --theme-* properties from the theme's Colour.* slots (ThemeService.CssVariables). Each rule
   below falls back to the design token when a slot is missing. */
.rj-shell {
    box-sizing: border-box;
    padding: calc(env(safe-area-inset-top) + 2rem) var(--pad) calc(1.25rem + var(--safe-b));
    background:
        radial-gradient(ellipse 120% 60% at 50% 34%, color-mix(in srgb, var(--theme-primary, var(--ground-pool)) 25%, transparent) 0%, transparent 68%),
        var(--theme-background, var(--ground));
    color: var(--theme-text, var(--ink));
    font-family: var(--font-body);
}

.rj-authored {
    margin: 0 0 var(--gap);
    padding: 0.5rem 0.75rem;
    border: 1px solid color-mix(in srgb, var(--theme-text, white) 16%, transparent);
    border-radius: var(--r-panel);
    font-size: 0.8rem;
    color: var(--theme-text-muted, var(--ink-2));
}

/* The connection shell (WebClientBase ConnectionOverlay) in the theme's colours: the wrapper maps the shell's own tokens to
   the theme's --theme-* properties, which the wrapper's style attribute sets. */
.rj-conn-theme {
    display: contents;
    --bg-card:        var(--theme-surface, var(--surface));
    --border-color:   color-mix(in srgb, var(--theme-text, white) 12%, transparent);
    --text-primary:   var(--theme-text, var(--ink));
    --text-secondary: var(--theme-text-muted, var(--ink-2));
    --gold:           var(--theme-accent, #f5c542);
    --on-gold:        var(--theme-button-text, #2a1f08);
    --danger:         var(--theme-danger, #fb7185);
    --hairline-strong: color-mix(in srgb, var(--theme-text, white) 16%, transparent);
}

/* The answer to an invite link, above the page (MetaLayout.razor). */
.rj-invite-notice {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0 0 var(--gap);
    padding: 0.6rem 0.75rem;
    border: 1px solid color-mix(in srgb, var(--theme-text, white) 16%, transparent);
    border-radius: var(--r-panel);
    background: var(--theme-surface, transparent);
    font-weight: 700;
}

.rj-invite-notice > span { flex: 1; }
.rj-invite-notice.is-good { color: var(--theme-success, var(--claim)); }
.rj-invite-notice.is-bad  { color: var(--theme-danger, var(--danger)); }

.rj-invite-notice__close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    min-width: 2.75rem;
    min-height: 2.75rem;
    margin: -0.5rem -0.6rem -0.5rem 0;
    border: 0;
    background: transparent;
    color: inherit;
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
}
