/* Shared readability, responsive controls and keyboard navigation. */
:root {
    --text-muted: #a1a1aa;
    --ui-focus: var(--gold, #d4af37);
}
[data-theme="light"] { --text-muted: #626873; --ui-focus: #806000; }
body { text-rendering: optimizeLegibility; }
:where(button, input, select, textarea) { font: inherit; }
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
    outline: 3px solid var(--ui-focus) !important;
    outline-offset: 4px;
}
:where(button, .btn, input[type="submit"]):disabled {
    cursor: not-allowed;
    opacity: .55;
}
:where(input, select, textarea) { max-width: 100%; }
:where(input, textarea)::placeholder { color: var(--text-muted); opacity: 1; }
:where(.form-label, .form-group > label) { display: block; margin-bottom: .5rem; }
:where(.form-control, .auth-form input:not([type="hidden"]), .login-form input:not([type="hidden"])) {
    min-height: 46px;
    font-size: 1rem;
}
:where(.btn, .header-btn, .sidebar-toggle, .alert-close, .table-actions button, .table-actions a) {
    min-height: 44px;
    min-width: 44px;
}
.skip-link {
    position: fixed;
    top: 12px;
    left: 12px;
    z-index: 2147483647;
    padding: .8rem 1.1rem;
    border-radius: 8px;
    background: var(--ui-focus);
    color: #111;
    font-weight: 700;
    transform: translateY(-200%);
}
.skip-link:focus { transform: translateY(0); }
[data-theme="light"] .skip-link { color: #fff; }
#main-content { scroll-margin-top: 100px; }
.table-responsive, .table-wrapper {
    max-width: 100%;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: thin;
}
.empty-state, .empty-state-modern { padding: clamp(1.5rem, 5vw, 3rem); }
.empty-state p, .empty-state-modern p { max-width: 46ch; margin-inline: auto; line-height: 1.65; }
.toast-container { pointer-events: none; }
.toast-container > * { pointer-events: auto; }
.auth-container { width: 100%; padding: clamp(1rem, 4vw, 2.5rem); }
.auth-card { width: min(100%, 460px); margin-inline: auto; }
.auth-header p, .auth-footer { line-height: 1.65; }

/* Admin working surface: clear hierarchy, quiet panels, readable data. */
body.admin-ui { --text-muted: #9ca8b8; --text-secondary: #b3becc; --ui-focus: var(--primary); font-size: 16px; }
.admin-ui .content-wrapper { max-width: 1680px; width: 100%; margin-inline: auto; }
.admin-ui .page-title { font-size: clamp(1.5rem, 2.4vw, 2rem); line-height: 1.25; letter-spacing: -.025em; }
.admin-ui .page-subtitle { font-size: .95rem; max-width: 70ch; line-height: 1.6; }
.admin-ui .card { border-color: var(--border-color); box-shadow: none; }
.admin-ui .card-header { gap: 1rem; flex-wrap: wrap; }
.admin-ui .form-control { border-color: #485363; border-radius: 8px; }
.admin-ui .table th { color: var(--text-secondary); font-size: .9rem; letter-spacing: .025em; }
.admin-ui .table td { font-size: .95rem; line-height: 1.55; }
.admin-ui .table th, .admin-ui .table td { padding: .9rem 1rem; }
.admin-ui .table tbody tr:hover { background: var(--bg-light); }
.admin-ui .nav-link { min-height: 44px; font-size: .95rem; }
.admin-ui .nav-link.active { box-shadow: inset 3px 0 var(--primary); }
.admin-ui .admin-dropdown.open .dropdown-menu,
.admin-ui .admin-dropdown:focus-within .dropdown-menu { opacity: 1; visibility: visible; transform: translateY(0); }
.admin-ui .stat-label, .admin-ui .form-label { font-size: .95rem; }
.admin-ui .table-responsive, .admin-ui .table-wrapper { margin-inline: 0; }

@media (max-width: 768px) {
    :where(input:not([type="checkbox"]):not([type="radio"]), select, textarea) { font-size: 16px !important; }
    .admin-ui .content-wrapper { padding: 1rem; }
    .admin-ui .page-header { gap: 1rem; }
    .admin-ui .table-actions { flex-wrap: nowrap; gap: .5rem; }
    .admin-ui .form-row { flex-wrap: wrap; }
    .admin-ui .form-row > .form-group { min-width: min(100%, 220px); flex: 1 1 220px; }
    .admin-ui .modal, .admin-ui .modal-content { max-width: calc(100vw - 2rem); max-height: calc(100dvh - 2rem); overflow-y: auto; }
    .bottom-nav { padding-bottom: env(safe-area-inset-bottom, 0px); }
    .auth-card { padding: 1.5rem; }
}
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
}

/* =====================================================
   HERO MOTION RESTRAINT
   =====================================================
   Measured on the signed-in home before this block: 148 animations running at
   once, 62 of them inside the hero, of which ~48 were infinite loops driven by
   purely decorative nodes - 12 particles, 4 orbs, 4 floating icons and 19
   waveform bars.

   Motion is not what makes a page look cheap; *unprompted, endless* motion is.
   Animation that answers something the reader did - a hover, a press, a page
   entering - reads as considered. Loops that run forever behind the content
   read as decoration, compete with the words, and on a phone they keep the
   compositor and the battery busy for as long as the tab is open. This site's
   readers are students on mobile data, so that cost is real.

   So: the one-shot entrance animations stay, and the perpetual ones stop. The
   orbs and the waveform are kept as static artwork - they still carry the
   "audio" identity, they just hold still.

   This file loads last, so these rules win without editing the originals.
   ===================================================== */

/* Pure noise: nothing is communicated by a drifting dot or a bouncing icon. */
.hero-particles,
.hero-floating-icons {
    display: none !important;
}

/* Depth without drift - the glow stays, the float stops. */
.hero-orbs .orb {
    animation: none !important;
    opacity: 0.5;
}

/* The waveform is the one decoration that means something on an audio product,
   so it stays - as a still graphic rather than 19 looping bars. */
.hero-audio-wave .audio-wave-svg .bar {
    animation: none !important;
}

.hero-waves-multi,
.hero-waves-multi * {
    animation: none !important;
}

/* Anything else in the hero that loops forever is decoration by definition.
   One-shot entrances (fadeInUp, heroFadeInUp, fadeInScale) are untouched. */
.hero-section [class*="sparkle"],
.hero-section [class*="glow-pulse"],
.hero-section [class*="shimmer"] {
    animation: none !important;
}

/* Motion that responds to the reader is the kind worth keeping, so make it
   feel deliberate rather than springy. */
.hero-cta .btn,
.hero-exam-card,
.exam-card-home,
.resume-card {
    transition: transform 0.18s cubic-bezier(0.4, 0, 0.2, 1),
                border-color 0.18s cubic-bezier(0.4, 0, 0.2, 1),
                background-color 0.18s cubic-bezier(0.4, 0, 0.2, 1),
                box-shadow 0.18s cubic-bezier(0.4, 0, 0.2, 1);
}

.hero-exam-card:hover,
.exam-card-home:hover {
    transform: translateY(-2px);
}

/* A reader who has asked their OS for less motion should get none of it,
   including the entrances the rules above deliberately kept. */
@media (prefers-reduced-motion: reduce) {

    .hero-section *,
    .resume-strip * {
        animation: none !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* The last two perpetual loops that were actually visible.

   .hero-scroll-indicator bounced forever. The hint is useful - it says there is
   more below - so the element stays; only the bounce goes. A cue that repeats
   every two seconds for as long as you read stops being a cue.

   .preview-card ran a skeleton shimmer on content that had already loaded, so
   the page permanently looked like it was still fetching something. */
.hero-scroll-indicator {
    animation: none !important;
}

.download-app-section .preview-card,
.preview-card {
    animation: none !important;
}

/* =====================================================
   HERO PROPORTION
   =====================================================
   The signed-in hero measured 1,386px tall - more than a full screen and a
   half of ambient artwork and generic CTAs before the reader reaches anything
   they came back for. With the resume strip now sitting above it, the hero's
   job is smaller: set the scene, offer the exam grid, get out of the way.

   Only spacing is touched; nothing inside is moved or hidden.
   ===================================================== */
.hero-section {
    min-height: 0;
    padding-top: 1.5rem;
    padding-bottom: 2rem;
}

.hero-content {
    padding-top: 0;
}

.hero-exams-section {
    margin: 1.25rem 0 !important;
}

.hero-cta {
    margin-top: 1.25rem;
}

.hero-stats {
    margin-top: 1.5rem;
}

@media (min-width: 768px) {
    .hero-section {
        padding-top: 2rem;
        padding-bottom: 2.5rem;
    }
}

/* =====================================================
   LONG-WORD / TALL-CARD GUARD  (Tamil-first content)
   =====================================================
   Tamil words are far longer than English ones, so a card sized for "Number
   System" can be handed "பாலஸ்தீனத்தின் வரலாற்றுப் பின்னணி" and, with no clamp,
   wrap to one word per line and grow into a tower - which is what a narrow
   column of these looks like on a phone.

   Every card component checked already clamps its own title (.ep-card-title,
   .episode-title, .section-card), so a blanket clamp here would only override
   working values - this file loads last and would have turned their 2 lines
   into 3. So the guard is limited to what cannot regress anything: a long word
   wraps instead of widening its column, and no page scrolls sideways.

   Only overflow behaviour is set - no colours, sizes or spacing are touched.
   ===================================================== */

/* A long unbroken word must wrap rather than widen its column. */
[class*="card"] [class*="title"],
[class*="card"] [class*="name"],
[class*="card"] [class*="sub"],
[class*="item"] [class*="title"],
[class*="item"] [class*="sub"] {
    overflow-wrap: anywhere;
    word-break: normal;
}

/* Nothing on a page should be able to scroll the whole document sideways. */
html,
body {
    overflow-x: hidden;
    max-width: 100%;
}

/* =====================================================
   TOUCH TARGETS
   =====================================================
   Two controls in the app header measured under 40px on a phone (the logo at
   32x32 and the account toggle at 30x30). The WCAG target-size minimum is
   44x44, and on a real thumb anything smaller is a mis-tap.

   The visible size is left alone - only the hit area grows, via padding that
   is cancelled by an equal negative margin so nothing moves on the page.
   ===================================================== */
.app-header .app-logo,
.app-header .user-menu-toggle,
.admin-theme-toggle,
.marketing-theme-toggle {
    position: relative;
}

.app-header .app-logo::after,
.app-header .user-menu-toggle::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 44px;
    height: 44px;
    transform: translate(-50%, -50%);
    /* the hit area only - never paints anything */
    background: transparent;
}
