/* ==========================================================================
   assets/css/polish.css — shared visual polish for every public page.

   Loaded by includes/i18n.php at the end of <head>, after each page's own
   <style> block. The rules here are refinements only: they never change a
   page's layout. Almost everything is wrapped in :where(), which has zero
   specificity, so any rule a page already sets (its own CSS or a Tailwind
   class) still wins and this file only fills the gaps.

   Two deliberate exceptions, so every public page matches:
     - the page background: a very light warm cream (see "Page background");
     - the font: Noto Sans Bengali for Bangla, Plus Jakarta Sans for Latin
       (see "Font"; includes/i18n.php loads both).
   ========================================================================== */

:root {
    --cs-accent: #ea580c;
    --cs-accent-soft: rgba(234, 88, 12, .16);
    --cs-ring: 0 0 0 3px rgba(234, 88, 12, .16);
    --cs-ease: cubic-bezier(.2, .8, .2, 1);
    --cs-fast: .16s;
    --cs-cream: #fffcf8;
    --cs-font: 'Plus Jakarta Sans', 'Noto Sans Bengali', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
}

/* --- Page background ------------------------------------------------------
   The site's one background colour: a very light warm cream, the same as
   the homepage and the report page. It wins over each page's own body
   colour (a <style> rule or a Tailwind bg-* class), which is why it is
   !important. Cards, panels and inputs stay white. A page with a
   deliberately dark design opts out with <body class="cs-keep-bg">.
   ------------------------------------------------------------------------ */
html:not(:has(> body.cs-keep-bg)) { background-color: var(--cs-cream); }
body:not(.cs-keep-bg) { background-color: var(--cs-cream) !important; }

/* Full-width grey Tailwind bands let the page background show through;
   white sections and every card stay white. */
:is(body:not(.cs-keep-bg), body:not(.cs-keep-bg) main) > section:is(.bg-slate-50, .bg-gray-50) { background-color: transparent; }

/* --- Font -----------------------------------------------------------------
   One font system on every page, over whatever each page's own CSS asks for:
   Plus Jakarta Sans draws Latin letters and numbers, and because it has no
   Bangla glyphs the browser uses Noto Sans Bengali for every Bangla character.
   Code and other monospace text keeps its own font.
   ------------------------------------------------------------------------ */
html body {
    font-family: var(--cs-font) !important;
    font-stretch: normal !important;
}
html body *:not(code):not(pre):not(kbd):not(samp):not(.font-mono):not([class*="mono"]) {
    font-family: var(--cs-font) !important;
    font-stretch: normal !important;
}

/* --- Rendering ----------------------------------------------------------- */

html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

body {
    text-rendering: optimizeLegibility;
    font-kerning: normal;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    -webkit-tap-highlight-color: transparent;
}

/* --- Typography ---------------------------------------------------------- */

/* Even line lengths in headings, no single-word last lines in paragraphs.
   Both only change where lines break, never how many boxes there are. */
:where(h1, h2, h3, h4) { text-wrap: balance; }
:where(p, li, dd, blockquote, figcaption) { text-wrap: pretty; }

/* Long phone numbers, URLs and names in running text wrap instead of pushing
   the page sideways on small screens. Only kicks in when a word overflows.
   Kept off small UI pieces (badges, stat labels) so "100%" never splits. */
:where(p, h1, h2, h3, h4, blockquote, dd) { overflow-wrap: break-word; }

/* Figures in stats and tables line up column by column. */
:where(.num, .cs-num, .tabular-nums, table) {
    font-variant-numeric: tabular-nums;
}

/* Plain text links (no class) inside content get a softer, readable underline. */
:where(p, li, dd, td, blockquote) a:where(:not([class])) {
    text-decoration-thickness: from-font;
    text-underline-offset: .18em;
}

::selection {
    background: var(--cs-accent-soft);
}

/* --- Form controls ------------------------------------------------------- */

:where(input, select, textarea, button) {
    font-family: inherit;
}

:where(input[type="checkbox"], input[type="radio"], input[type="range"], progress) {
    accent-color: var(--cs-accent);
}

:where(input, textarea) {
    caret-color: var(--cs-accent);
}

:where(textarea) {
    line-height: 1.6;
}

:where(button, [role="button"], summary, select, label[for], input[type="submit"], input[type="button"], input[type="checkbox"], input[type="radio"]) {
    cursor: pointer;
}

:where(button, input, select, textarea):disabled,
:where([aria-disabled="true"]) {
    cursor: not-allowed;
}

/* --- Interactive states -------------------------------------------------- */

/* Colour-only transitions: safe for elements whose position or size is
   animated by JavaScript, and overridden by any page-level `transition`. */
:where(a, button, [role="button"], summary, label, input, select, textarea) {
    transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, box-shadow, outline-color;
    transition-duration: var(--cs-fast);
    transition-timing-function: var(--cs-ease);
}

/* Keyboard focus is always visible. Mouse and touch clicks do not show it. */
:where(a, button, [role="button"], summary, [tabindex]:not([tabindex="-1"])):focus-visible {
    outline: 2px solid var(--cs-accent);
    outline-offset: 2px;
}

:where(input:not([type="checkbox"]):not([type="radio"]):not([type="range"]), select, textarea):focus-visible {
    outline: 2px solid var(--cs-accent);
    outline-offset: 1px;
}

:where(input[type="checkbox"], input[type="radio"]):focus-visible {
    outline: 2px solid var(--cs-accent);
    outline-offset: 2px;
}

/* Tailwind's `focus:outline-none` also hides the ring for keyboard users.
   Put it back on buttons and links that do not bring a ring of their own.
   Fields are left alone: they usually style focus on their wrapper. */
.focus\:outline-none:not(input):not(textarea):not(select):not([class*="focus:ring"]):not([class*="focus-visible:"]):focus-visible {
    outline: 2px solid var(--cs-accent);
    outline-offset: 2px;
}

/* A gentle press for buttons. `scale` composes with any existing transform
   (e.g. translateX(-50%) on a centred button) instead of replacing it. */
:where(button, [role="button"], input[type="submit"], input[type="button"]):where(:not(:disabled)):active {
    scale: .985;
}

/* --- Touch devices ------------------------------------------------------- */

/* Removes the double-tap-to-zoom delay on buttons and links. */
:where(a, button, [role="button"], summary, label, input, select, textarea) {
    touch-action: manipulation;
}

/* iOS Safari zooms the whole page when a field under 16px gets focus, then
   leaves it zoomed. Fields are bumped to 16px on iOS only. */
@supports (-webkit-touch-callout: none) {
    @media (max-width: 768px) {
        input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="submit"]):not([type="button"]),
        select,
        textarea {
            font-size: max(16px, 1em) !important;
        }
    }
}

/* Footer link rows are single lines of 13–14px text. On touch screens the
   tap area grows to ~36px tall; the negative margin keeps the layout exact. */
@media (pointer: coarse) {
    footer :where(.flex, .flex-wrap) > a:where([class*="text-"]):where(:not([class*="p-"]):not([class*="py-"]):not([class*="w-"]):not([class*="h-"])) {
        padding-block: 8px;
        margin-block: -8px;
    }
}

/* --- Media --------------------------------------------------------------- */

/* Pictures cannot be dragged out, selected, or saved with a long press
   (iOS "Save to Photos"). Right-click "Save image" is blocked in prefs.js.
   Uploaded pictures also come through protected, expiring /media.php links. */
img, picture, video, canvas {
    -webkit-user-drag: none;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
}

/* Long unbroken strings in code and pre blocks wrap instead of overflowing. */
:where(pre) {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* Wide tables inside a scroll wrapper scroll smoothly on iOS. */
:where([class*="overflow-x-auto"], [class*="table-wrap"], [class*="tbl-wrap"]) {
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
}

/* --- Corners --------------------------------------------------------------
   Cards across the site use slightly crisper corners: 12px for cards and
   panels, 16px for the largest boxes. Pages set their own radii in their
   CSS; these lines only bring Tailwind's big rounded-* classes in line.
   ------------------------------------------------------------------------ */
html body .rounded-2xl { border-radius: 12px; }
html body .rounded-3xl { border-radius: 16px; }
html body .rounded-t-2xl { border-top-left-radius: 12px; border-top-right-radius: 12px; }
html body .rounded-t-3xl { border-top-left-radius: 16px; border-top-right-radius: 16px; }

/* --- Motion -------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
    :where(button, [role="button"], input[type="submit"], input[type="button"]):active {
        scale: none;
    }
}

/* --- Print --------------------------------------------------------------- */

@media print {
    body { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
    :where(a) { text-decoration: underline; }
}

/* ==========================================================================
   Layout helpers shared by every page (desktop + mobile)
   ========================================================================== */

/* The white-to-dark "fade" strips under the header read as a grey smear;
   the dark heroes now start cleanly under the white header. */
.hero-top-fade, .hero-bottom-fade, .hero-fade { display: none !important; }

/* Pages opt in to a wider desktop layout with these classes:
     .cs-wide       — the page column grows from phone width to 1120px
     .cs-wide-grid  — its list becomes two columns on large screens
     .cs-span       — an item inside that grid that spans both columns */
@media (min-width: 1024px) {
    html body .cs-wide { max-width: 1120px !important; }
    html body .cs-wide-md { max-width: 880px !important; }
    html body .cs-wide-grid {
        display: grid !important;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 20px;
        align-items: start;
    }
    html body .cs-wide-grid > * { margin-top: 0 !important; margin-bottom: 0 !important; min-width: 0; }
    html body .cs-wide-grid > .cs-span { grid-column: 1 / -1; }
}

/* Phone bottom navigation → a floating dock on desktop, instead of a bar
   stretched across a wide screen. (Pages that hide it on desktop keep
   doing so; their own display:none still wins.) */
@media (min-width: 1024px) {
    html body .cs-bottom-nav,
    html body nav.bottom-nav {
        left: 50%;
        right: auto;
        bottom: 16px;
        width: min(560px, calc(100vw - 32px));
        transform: translateX(-50%);
        border-radius: 14px;
        border: 1px solid rgba(226, 232, 240, .9);
        box-shadow: 0 1px 2px rgba(15, 23, 42, .06), 0 18px 40px -18px rgba(15, 23, 42, .35);
        padding-bottom: 0;
        overflow: visible;
    }
    html body nav.bottom-nav { border-color: rgba(255, 255, 255, .12); }
    /* The report form's step bar: the same width as the form above it. */
    html body #bnav.cs-bottom-nav { width: min(672px, calc(100vw - 32px)); }
}

/* ── Star tiles: the one rating look on every page ─────────────────────────
   A white star on a square coloured by the rating — 5 green, 4 light green,
   3 amber, 2 orange, 1 red; grey when empty, half-filled for .5. Markup comes
   from cs_stars() (includes/stars.php) or csStars() (assets/js/prefs.js):
   <span class="cs-st [cs-st-lg|sm|xs] [cs-st-dark]" data-r="1-5"><i class="on|half"></i>…</span>
   "span.cs-st > i" outranks a page's own "i" rules (e.g. a logo letter in an <i>). */
.cs-st { --s: 18px; --c: #dcdee5; --off: #dcdee5; display: inline-flex; gap: 2px; vertical-align: middle; flex: none; line-height: 0; }
span.cs-st > i { position: relative; flex: none; width: var(--s); height: var(--s); border-radius: calc(var(--s) * .22); background: var(--off); font-style: normal; }
span.cs-st > i::before { content: ""; position: absolute; inset: 16%; background: #fff;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 1.8l3.1 6.6 7.1.9-5.2 5 1.3 7.1L12 17.9l-6.3 3.5 1.3-7.1-5.2-5 7.1-.9z'/%3E%3C/svg%3E") center/contain no-repeat;
            mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 1.8l3.1 6.6 7.1.9-5.2 5 1.3 7.1L12 17.9l-6.3 3.5 1.3-7.1-5.2-5 7.1-.9z'/%3E%3C/svg%3E") center/contain no-repeat; }
span.cs-st > i.on { background: var(--c); }
span.cs-st > i.half { background: linear-gradient(90deg, var(--c) 50%, var(--off) 50%); }
.cs-st[data-r="5"] { --c: #00b67a; } .cs-st[data-r="4"] { --c: #73cf11; } .cs-st[data-r="3"] { --c: #f5b800; }
.cs-st[data-r="2"] { --c: #ff8622; } .cs-st[data-r="1"] { --c: #ff3722; }
.cs-st-lg { --s: 20px; gap: 3px; }
@media (min-width: 640px) { .cs-st-lg { --s: 22px; } }
.cs-st-sm { --s: 15px; }
.cs-st-xs { --s: 12px; gap: 1.5px; }
.cs-st-dark { --off: rgba(255, 255, 255, .16); }
/* A tile and the score side by side: "[★] 4.5". */
.cs-sts { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; font-weight: 800; color: #0f172a; font-size: 12.5px; line-height: 1; }
.cs-sts > b { font-weight: 800; }
