/* Exo (SIL OFL 1.1) — self-hosted copy of Google Fonts' files.
   Served from our own origin: no extra DNS/TLS on a cold app start, which
   delayed Safari's first paint by ~1.3 s while text waited for the font. */
@font-face {
  font-family: 'Exo';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url(../fonts/exo/exo-vietnamese-italic.woff2?v=8d746f9e0c) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'Exo';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url(../fonts/exo/exo-latin-ext-italic.woff2?v=12526ee5d9) 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-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Exo';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url(../fonts/exo/exo-latin-italic.woff2?v=f3a769b9a4) 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: 'Exo';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url(../fonts/exo/exo-vietnamese-normal.woff2?v=b7c3811f86) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'Exo';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url(../fonts/exo/exo-latin-ext-normal.woff2?v=f94b6f8f35) 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-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Exo';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url(../fonts/exo/exo-latin-normal.woff2?v=fa42d74461) 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;
}

/* kx-ui.css — Keryx interaction & motion layer
   Loaded on every page after tailwind.min.css / smooth.css.
   One place for: motion tokens, touch feedback, safe areas, scroll behaviour,
   focus rings, toasts, page transitions and the installed-app (standalone) feel.
   Brand accents are unchanged: #49789f blue, #2c9ca7 teal, #843dff purple.
   ─────────────────────────────────────────────────────────────────────────── */

:root {
    /* Motion — iOS-like curves: quick start, long soft settle */
    --kx-ease:        cubic-bezier(.22, 1, .36, 1);
    --kx-ease-in:     cubic-bezier(.4, 0, 1, 1);
    --kx-spring:      cubic-bezier(.34, 1.4, .64, 1);
    --kx-dur-press:   110ms;
    --kx-dur-fast:    180ms;
    --kx-dur:         280ms;
    --kx-dur-slow:    420ms;

    /* Shape */
    --kx-radius-sm:   10px;
    --kx-radius:      14px;
    --kx-radius-lg:   20px;
    --kx-radius-xl:   28px;

    /* Surfaces */
    --kx-hairline:    rgba(15, 23, 42, .08);
    --kx-page-bg:     #f8fafc;
    --kx-brand:       #49789f;
    --kx-brand-2:     #2c9ca7;
    --kx-brand-3:     #843dff;

    /* Layout */
    --kx-safe-top:    env(safe-area-inset-top, 0px);
    --kx-safe-bottom: env(safe-area-inset-bottom, 0px);
    --kx-nav-h:       4rem;
    --kx-tabbar-h:    calc(3.25rem + var(--kx-safe-bottom));
}
.dark {
    --kx-hairline:    rgba(255, 255, 255, .07);
    --kx-page-bg:     #0f172a;
}

/* ── Base ─────────────────────────────────────────────────────────────────── */
html {
    -webkit-tap-highlight-color: transparent;
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    /* Rubber-band overscroll shows this colour — match the page, not white */
    background-color: var(--kx-page-bg);
    /* Anchor jumps land below the sticky header */
    scroll-padding-top: calc(var(--kx-nav-h) + var(--kx-safe-top) + .75rem);
}
html, body { overflow-x: clip; } /* nothing off-canvas may cause sideways scroll */
body {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}
::selection { background: rgba(73, 120, 159, .22); }

/* Kill the 300 ms double-tap-zoom wait on every control */
a, button, [role="button"], label, summary, select,
input[type="checkbox"], input[type="radio"] {
    touch-action: manipulation;
}
/* Chrome UI shouldn't select like text when long-pressed */
button, [role="button"], nav, .kx-tabbar {
    -webkit-user-select: none;
    user-select: none;
}
img { -webkit-user-drag: none; }

/* ── Focus: visible for keyboards, invisible for taps ─────────────────────── */
:focus:not(:focus-visible) { outline: none; }
:focus-visible {
    outline: 2px solid var(--kx-brand);
    outline-offset: 2px;
    border-radius: 6px;
}
.dark :focus-visible { outline-color: #8fb3d1; }

/* ── Press feedback (touch devices) ───────────────────────────────────────────
   Uses the individual `scale` property so it composes with any transform the
   element already has (centering translate, rotations…) instead of replacing it. */
@media (hover: none) and (pointer: coarse) {
    button:not(:disabled), [role="button"], .kx-press, .kx-btn-primary,
    nav a, .kx-tabbar a, .kx-tabbar button,
    .feed-item, .hero-featured-card, .hero-now-card, .circle-card, .article-card {
        transition: scale var(--kx-dur-press) var(--kx-ease),
                    opacity var(--kx-dur-press) var(--kx-ease),
                    background-color var(--kx-dur-fast) ease,
                    color var(--kx-dur-fast) ease,
                    border-color var(--kx-dur-fast) ease;
    }
    button:not(:disabled):active, [role="button"]:active, .kx-press:active,
    .kx-btn-primary:active, nav a:active {
        scale: .96;
        opacity: .82;
    }
    .kx-tabbar a:active, .kx-tabbar button:active { scale: .9; opacity: 1; }
    .feed-item:active, .hero-now-card:active, .circle-card:active,
    .article-card:active { scale: .985; }
    .hero-featured-card:active { scale: .98; }

    /* Hover effects "stick" after a tap on touch screens — and some of these
       shift layout (negative margins). Neutralise them. Extra `html` raises
       specificity above the page-level <style> blocks. */
    html .feed-item:hover,
    html .hero-now-card:hover {
        margin: 0;
        padding-left: 0;
        padding-right: 0;
        background: transparent;
    }
    html .feed-item:hover .feed-title,
    html .hero-now-card:hover .hero-list-title { color: inherit; }
    html .side-article:hover,
    html .article-card:hover,
    html .circle-card:hover { transform: none; box-shadow: none; }
    html .article-card:hover .article-image,
    html .group:hover .group-hover\:scale-105 { transform: none; }
}

/* ── Phones: comfortable inputs, keyboard-aware chrome, bigger hit areas ──── */
@media (pointer: coarse) {
    /* 16px stops iOS zooming into a field on focus (pinch-zoom stays allowed) */
    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]),
    textarea, select { font-size: 16px; }

    /* While typing, fixed bottom chrome would ride up on the keyboard — hide it */
    body:has(:is(input:not([type="checkbox"]):not([type="radio"]), textarea, [contenteditable="true"]):focus)
        :is(.kx-tabbar, .tts-player-wrap, #signup-cta-wrap, #pwa-install-banner, #ios-install-banner, .kx-snap-fab) {
        display: none !important;
    }

    /* Small icon chips keep their look but get a ~44px touch target */
    .feed-item button, .feed-item a:not(.feed-stretch),
    .hero-featured-card button, .hero-featured-card a,
    .kx-hit, #signup-cta-dismiss, #pwa-install-banner button, #ios-install-banner button {
        position: relative;
    }
    .feed-item button::after, .feed-item a:not(.feed-stretch)::after,
    .hero-featured-card button::after, .hero-featured-card a::after,
    .kx-hit::after, #signup-cta-dismiss::after,
    #pwa-install-banner button::after, #ios-install-banner button::after {
        content: '';
        position: absolute;
        inset: -8px;
    }
}

/* ── Scroll containers ─────────────────────────────────────────────────────── */
/* Drawers, sheets and modals: scrolling inside them never drags the page */
#mobile-drawer, [role="dialog"], .kx-sheet, .overflow-y-auto, .overflow-auto {
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
}
.overflow-x-auto { overscroll-behavior-x: contain; }

/* Horizontal snap rails (e.g. "Right now" on phones) */
.kx-rail {
    display: flex;
    gap: .75rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: 1rem;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
}
.kx-rail::-webkit-scrollbar { display: none; }
.kx-rail > * { scroll-snap-align: start; flex-shrink: 0; }

/* Long feeds: let the browser skip rendering off-screen cards */
.feed-item {
    content-visibility: auto;
    contain-intrinsic-size: auto 132px;
}

/* ── Installed app (standalone) ────────────────────────────────────────────── */
@media (display-mode: standalone) {
    /* The iOS status bar is translucent: keep the header clear of the clock/notch */
    #main-navbar { padding-top: var(--kx-safe-top); }
}
html.kx-standalone #main-navbar { padding-top: var(--kx-safe-top); }

/* ── Bottom tab bar ────────────────────────────────────────────────────────── */
.kx-tabbar {
    padding-bottom: var(--kx-safe-bottom);
    background: rgba(255, 255, 255, .86);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    backdrop-filter: saturate(180%) blur(20px);
    border-top: .5px solid var(--kx-hairline);
}
.dark .kx-tabbar { background: rgba(3, 7, 18, .82); }
.kx-tabbar .kx-tab {
    position: relative;
    display: flex;
    flex: 1 1 0;
    min-width: 0;
    min-height: 3.25rem;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    color: #8a94a6;
}
.dark .kx-tabbar .kx-tab { color: #6b7280; }
.kx-tabbar .kx-tab span {
    font-size: 10px;
    line-height: 1;
    font-weight: 600;
    letter-spacing: .01em;
    white-space: nowrap;
}
.kx-tabbar .kx-tab.is-active,
.kx-tabbar .kx-tab[aria-current="page"] { color: var(--kx-brand); }
.dark .kx-tabbar .kx-tab.is-active,
.dark .kx-tabbar .kx-tab[aria-current="page"] { color: #8fb3d1; }
.kx-tabbar .kx-tab svg,
.kx-tabbar .kx-tab i {
    transition: transform var(--kx-dur) var(--kx-spring);
}
.kx-tabbar .kx-tab.is-active svg,
.kx-tabbar .kx-tab[aria-current="page"] svg {
    transform: translateY(-1px) scale(1.06);
    stroke-width: 2.1;
}
/* Floating cards that must clear the tab bar + home indicator on phones */
.kx-above-tabbar { bottom: calc(var(--kx-tabbar-h) + .75rem); }
@media (min-width: 1024px) { .kx-above-tabbar { bottom: 1rem; } }
/* Pages with the tab bar: keep the last row of content above it */
.kx-has-tabbar { padding-bottom: calc(var(--kx-tabbar-h) + 1rem); }
@media (min-width: 1024px) { .kx-has-tabbar { padding-bottom: 0; } }

/* ── Toasts (single, top-centre, iOS style) ─────────────────────────────────── */
.kx-toast-host {
    position: fixed;
    left: 0;
    right: 0;
    top: calc(var(--kx-safe-top) + .75rem);
    z-index: 200;
    display: flex;
    justify-content: center;
    pointer-events: none;
    padding: 0 1rem;
}
.kx-toast {
    pointer-events: auto;
    display: inline-flex;
    align-items: center;
    gap: .55rem;
    max-width: min(26rem, 100%);
    padding: .7rem 1rem .7rem .85rem;
    border-radius: 9999px;
    font-size: .8125rem;
    font-weight: 600;
    line-height: 1.3;
    color: #0f172a;
    background: rgba(255, 255, 255, .92);
    -webkit-backdrop-filter: saturate(180%) blur(18px);
    backdrop-filter: saturate(180%) blur(18px);
    border: .5px solid rgba(15, 23, 42, .08);
    box-shadow: 0 10px 30px -8px rgba(15, 23, 42, .25), 0 2px 6px rgba(15, 23, 42, .06);
    opacity: 0;
    transform: translateY(-14px) scale(.96);
    transition: opacity var(--kx-dur) var(--kx-ease), transform var(--kx-dur-slow) var(--kx-spring);
}
.dark .kx-toast {
    color: #f8fafc;
    background: rgba(30, 41, 59, .9);
    border-color: rgba(255, 255, 255, .08);
}
.kx-toast.is-in { opacity: 1; transform: none; }
.kx-toast.is-out {
    opacity: 0;
    transform: translateY(-8px) scale(.98);
    transition-duration: var(--kx-dur-fast);
    transition-timing-function: var(--kx-ease-in);
}
.kx-toast-dot {
    width: 1.35rem;
    height: 1.35rem;
    border-radius: 9999px;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-size: .7rem;
}
.kx-toast--success .kx-toast-dot { background: #22a06b; }
.kx-toast--error   .kx-toast-dot { background: #e5484d; }
.kx-toast--warning .kx-toast-dot { background: #f5a524; }
.kx-toast--info    .kx-toast-dot { background: var(--kx-brand); }

/* Confirm sheet (replaces the slide-in confirm toast) */
.kx-confirm-backdrop {
    position: fixed;
    inset: 0;
    z-index: 210;
    background: rgba(2, 6, 23, .38);
    opacity: 0;
    transition: opacity var(--kx-dur) var(--kx-ease);
}
.kx-confirm {
    position: fixed;
    left: 50%;
    bottom: calc(var(--kx-safe-bottom) + 1rem);
    z-index: 211;
    width: min(22rem, calc(100% - 2rem));
    padding: 1.1rem;
    border-radius: var(--kx-radius-lg);
    background: #fff;
    color: #0f172a;
    box-shadow: 0 24px 60px -12px rgba(2, 6, 23, .35);
    transform: translate(-50%, 24px);
    opacity: 0;
    transition: opacity var(--kx-dur) var(--kx-ease), transform var(--kx-dur-slow) var(--kx-spring);
}
.dark .kx-confirm { background: #1e293b; color: #f8fafc; }
@media (min-width: 640px) {
    .kx-confirm { bottom: auto; top: 50%; transform: translate(-50%, -46%); }
}
.kx-confirm.is-in { opacity: 1; transform: translate(-50%, 0); }
@media (min-width: 640px) { .kx-confirm.is-in { transform: translate(-50%, -50%); } }
.kx-confirm-backdrop.is-in { opacity: 1; }

/* ── Pull to refresh (installed app only — there's no browser reload button) ── */
.kx-ptr {
    position: fixed;
    left: 50%;
    top: calc(var(--kx-safe-top) + .5rem);
    z-index: 150;
    width: 2.25rem;
    height: 2.25rem;
    margin-left: -1.125rem;
    border-radius: 9999px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--kx-brand);
    background: rgba(255, 255, 255, .95);
    box-shadow: 0 6px 18px -4px rgba(15, 23, 42, .25);
    opacity: 0;
    transform: translateY(-3rem);
    pointer-events: none;
}
.dark .kx-ptr { background: rgba(30, 41, 59, .95); color: #8fb3d1; }
.kx-ptr svg { width: 1.1rem; height: 1.1rem; }
.kx-ptr.is-releasing { transition: transform var(--kx-dur) var(--kx-ease), opacity var(--kx-dur) var(--kx-ease); }
.kx-ptr.is-loading svg { animation: kx-spin .8s linear infinite; }
@keyframes kx-spin { to { transform: rotate(360deg); } }

/* ── Page transitions (Chrome/Edge 126+, Safari 18.2+; ignored elsewhere) ─── */
@media (prefers-reduced-motion: no-preference) {
    @view-transition { navigation: auto; }
    ::view-transition-old(root) { animation: kx-vt-out 140ms var(--kx-ease-in) both; }
    ::view-transition-new(root) { animation: kx-vt-in 220ms var(--kx-ease) both; }
}
@keyframes kx-vt-out { to { opacity: 0; } }
@keyframes kx-vt-in  { from { opacity: 0; } }

/* Smooth in-page scrolling, unless the user asked for less motion */
@media (prefers-reduced-motion: no-preference) {
    html { scroll-behavior: smooth; }
}

/* ── Reduced motion: global safety net ─────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
}
