/* =============================================================================
   DRONA BOOKS PORTAL — PUBLIC STYLES
   File    : assets/css/site.css
   Version : 1.0.0
   Date    : 2026-08-24
   =============================================================================

   Mobile-first, hand-written, no framework. About 12KB — which matters, because
   most trainers open this from a WhatsApp link on a low-end Android phone over
   patchy mobile data. A 200KB CSS framework would be most of the page weight
   and would buy nothing this file does not already do.

   KANNADA TYPOGRAPHY
   ------------------
   Kannada needs more vertical room than Latin: the script stacks vowel signs
   above and below the baseline, and conjunct consonants hang below it. With a
   normal 1.4 line-height the marks of one line collide with the next. Every
   line-height here is 1.6 or more, and Kannada text gets 1.75.

   TOUCH TARGETS
   -------------
   Every tappable thing is at least 44px tall. That is not a style choice — it
   is the minimum a thumb can hit reliably on a phone being used one-handed,
   which is how this form will actually be filled in.
   ========================================================================== */

/* ---------- Tokens ---------- */
:root {
    --green:        #1a5f3f;
    --green-dark:   #12452e;
    --green-light:  #e8f3ed;
    --amber:        #b45309;
    --amber-light:  #fef3c7;
    --red:          #b91c1c;
    --red-light:    #fee2e2;
    --blue:         #1d4ed8;
    --blue-light:   #dbeafe;
    /* The gold from the logo. Used where something has to read as "you are
       here" on the green bar without competing with the call to action. */
    --gold:         #d4a017;

    --ink:          #14181f;
    --ink-soft:     #4b5563;
    --ink-faint:    #6b7280;
    --line:         #e2e5ea;
    --bg:           #f7f8fa;
    --card:         #ffffff;

    --radius:       10px;
    --radius-sm:    6px;
    --shadow:       0 1px 2px rgba(16, 24, 40, .05), 0 1px 3px rgba(16, 24, 40, .08);
    --shadow-lg:    0 4px 12px rgba(16, 24, 40, .10);

    --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Noto Sans", sans-serif;
    --font-kn: "Noto Sans Kannada", "Tunga", "Nirmala UI", var(--font);
}

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

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

body {
    margin: 0;
    font-family: var(--font);
    font-size: 16px;          /* never below 16px: iOS zooms the page on focus otherwise */
    line-height: 1.6;
    color: var(--ink);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
}

html[lang^="kn"] body,
.kn {
    font-family: var(--font-kn);
    line-height: 1.75;        /* room for stacked vowel signs and conjuncts */
}

img { max-width: 100%; height: auto; display: block; }

h1, h2, h3, h4 { margin: 0 0 .5em; line-height: 1.3; font-weight: 650; }
h1 { font-size: 1.55rem; }
h2 { font-size: 1.25rem; }
h3 { font-size: 1.05rem; }

html[lang^="kn"] h1, html[lang^="kn"] h2, html[lang^="kn"] h3 { line-height: 1.5; }

p { margin: 0 0 1em; }
a { color: var(--green); }

/* ---------- Layout ---------- */
.wrap { width: 100%; max-width: 720px; margin: 0 auto; padding: 0 16px; }
.wrap-wide { max-width: 1100px; }

.section { padding: 28px 0; }
.section-tight { padding: 16px 0; }

.card {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 20px 18px;
    margin-bottom: 16px;
    box-shadow: var(--shadow);
}

.stack > * + * { margin-top: 14px; }
.row { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; }
.row-between { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.grow { flex: 1 1 auto; min-width: 0; }
.center { text-align: center; }
.muted { color: var(--ink-faint); }
.small { font-size: .875rem; }
.tiny  { font-size: .8rem; }
.strong { font-weight: 650; }
.nowrap { white-space: nowrap; }
.hidden { display: none !important; }

/* ---------- Header ---------- */
.site-header {
    background: var(--green);
    color: #fff;
    padding: 12px 0;
    position: sticky;
    top: 0;
    z-index: 40;
}
.site-header a { color: #fff; text-decoration: none; }
.brand { font-weight: 700; font-size: 1.05rem; letter-spacing: .2px; }
.brand-sub { font-size: .78rem; opacity: .85; font-weight: 400; }

.lang-toggle {
    border: 1px solid rgba(255,255,255,.45);
    border-radius: 999px;
    padding: 7px 14px;
    font-size: .85rem;
    min-height: 38px;
    display: inline-flex;
    align-items: center;
    background: rgba(255,255,255,.08);
}

/* ---------- Banner ---------- */
.banner {
    padding: 12px 16px;
    text-align: center;
    font-weight: 600;
    font-size: .95rem;
    border-bottom: 1px solid var(--line);
}
.banner-open      { background: var(--green-light); color: var(--green-dark); }
.banner-closing   { background: var(--amber-light); color: var(--amber); }
.banner-closed    { background: var(--red-light);   color: var(--red); }
.banner-info      { background: var(--blue-light);  color: var(--blue); }
.banner .countdown { font-variant-numeric: tabular-nums; }

/* ---------- Buttons ---------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 48px;               /* thumb-sized */
    padding: 12px 22px;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    font: inherit;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    transition: background .12s ease, transform .06s ease;
    -webkit-tap-highlight-color: transparent;
}
.btn:active { transform: translateY(1px); }

.btn-primary   { background: var(--green); color: #fff; }
.btn-primary:hover { background: var(--green-dark); }
.btn-secondary { background: #fff; color: var(--ink); border-color: var(--line); }
.btn-whatsapp  { background: #25d366; color: #fff; }
.btn-block     { width: 100%; }
.btn-lg        { min-height: 56px; font-size: 1.05rem; }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .55; pointer-events: none; }

/* ---------- Forms ---------- */
.field { margin-bottom: 18px; }

.field label {
    display: block;
    font-weight: 600;
    font-size: .92rem;
    margin-bottom: 6px;
}
.field .hint { font-size: .82rem; color: var(--ink-faint); margin-top: 5px; }

.field input[type="text"],
.field input[type="tel"],
.field input[type="email"],
.field input[type="number"],
.field input[type="password"],
.field select,
.field textarea {
    width: 100%;
    min-height: 48px;
    padding: 12px 13px;
    font: inherit;
    font-size: 16px;            /* prevents the iOS zoom-on-focus */
    color: var(--ink);
    background: #fff;
    border: 1.5px solid var(--line);
    border-radius: var(--radius-sm);
    appearance: none;
}
.field textarea { min-height: 92px; resize: vertical; line-height: 1.6; }

.field select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%236b7280' stroke-width='2' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 14px center;
    padding-right: 38px;
}

.field input:focus, .field select:focus, .field textarea:focus {
    outline: none;
    border-color: var(--green);
    box-shadow: 0 0 0 3px rgba(26, 95, 63, .13);
}

.field.has-error input,
.field.has-error select,
.field.has-error textarea { border-color: var(--red); }

.field .error { color: var(--red); font-size: .85rem; margin-top: 5px; font-weight: 500; }

.required::after { content: " *"; color: var(--red); }

/* The honeypot — visually gone, but still a real field a bot will fill. */
.hp {
    position: absolute !important;
    left: -9999px;
    width: 1px; height: 1px;
    overflow: hidden;
}

/* ---------- Live price summary ---------- */
.summary {
    background: var(--green-light);
    border: 1px solid #cfe3d8;
    border-radius: var(--radius);
    padding: 16px;
}
.summary-line {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 5px 0;
    font-size: .95rem;
}
.summary-line.total {
    border-top: 1.5px solid #cfe3d8;
    margin-top: 8px;
    padding-top: 11px;
    font-size: 1.2rem;
    font-weight: 700;
    color: var(--green-dark);
}
.summary-line .amount { font-variant-numeric: tabular-nums; white-space: nowrap; }
.summary-line.discount .amount { color: var(--green); }

/* ---------- Price tiers ---------- */
.tiers { width: 100%; border-collapse: collapse; font-size: .95rem; }
.tiers th, .tiers td { padding: 11px 10px; text-align: left; border-bottom: 1px solid var(--line); }
.tiers th { font-weight: 650; color: var(--ink-soft); font-size: .85rem; }
.tiers td:last-child, .tiers th:last-child { text-align: right; font-variant-numeric: tabular-nums; }
.tiers tr.active { background: var(--green-light); font-weight: 650; }

/* ---------- Booking ID display ---------- */
.booking-id {
    font-size: 1.9rem;
    font-weight: 700;
    letter-spacing: 1px;
    color: var(--green-dark);
    font-variant-numeric: tabular-nums;
    word-break: break-all;
}

/* ---------- Slot buttons ---------- */
.slots { display: grid; gap: 12px; }
.slot {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    width: 100%;
    min-height: 62px;
    padding: 14px 18px;
    background: #fff;
    border: 2px solid var(--line);
    border-radius: var(--radius);
    font: inherit;
    text-align: left;
    cursor: pointer;
}
.slot:hover { border-color: var(--green); }
.slot .slot-label  { font-weight: 650; }
.slot .slot-amount { font-size: 1.2rem; font-weight: 700; color: var(--green-dark); font-variant-numeric: tabular-nums; }
.slot.recommended  { border-color: var(--green); background: var(--green-light); }
.slot .slot-tag {
    display: inline-block;
    font-size: .72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .4px;
    color: var(--green);
}

/* ---------- Pick-one cards (3.0) ----------
   A radio group where the WHOLE CARD is the tap target, not a 20px circle
   beside it. On a low-end phone held one-handed that difference is the whole
   difference between choosing "bus parcel" and choosing "courier" by mistake.

   The input is stretched to fill its card and made transparent rather than
   hidden: it stays in the tab order, still announces itself to a screen reader,
   and its hit area genuinely IS the card — which is what the layout check
   measures, so the check keeps telling the truth instead of being worked
   around. The visible circle is drawn by .pick-dot beside it. */
.pick { position: relative; }
.pick input[type="radio"] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    opacity: 0;
    cursor: pointer;
    z-index: 1;
}
.pick-dot {
    flex: 0 0 auto;
    width: 22px;
    height: 22px;
    margin-right: 12px;
    border: 2px solid var(--line);
    border-radius: 50%;
    background: #fff;
    display: inline-block;
    vertical-align: middle;
    position: relative;
}
.pick input[type="radio"]:checked ~ * .pick-dot,
.pick input[type="radio"]:checked ~ .pick-dot { border-color: var(--green); }
.pick input[type="radio"]:checked ~ * .pick-dot::after,
.pick input[type="radio"]:checked ~ .pick-dot::after {
    content: "";
    position: absolute;
    inset: 3px;
    border-radius: 50%;
    background: var(--green);
}
/* Keyboard focus has to be visible on the CARD, because the input itself is
   transparent — otherwise tabbing through the group shows nothing at all. */
.pick:focus-within { border-color: var(--green); box-shadow: 0 0 0 3px var(--green-light); }
.pick input[type="radio"]:checked ~ * .pick-label { font-weight: 700; }

/* ---------- Status badges ---------- */
.badge {
    display: inline-block;
    padding: 4px 10px;
    border-radius: 999px;
    font-size: .78rem;
    font-weight: 650;
    white-space: nowrap;
}
.badge-grey       { background: #eef0f3; color: #4b5563; }
.badge-amber      { background: var(--amber-light); color: var(--amber); }
.badge-blue       { background: var(--blue-light); color: var(--blue); }
.badge-green      { background: var(--green-light); color: var(--green-dark); }
.badge-green-dark { background: var(--green); color: #fff; }
.badge-teal       { background: #ccfbf1; color: #0f766e; }
.badge-red        { background: var(--red-light); color: var(--red); }
.badge-muted      { background: #f1f2f4; color: #9ca3af; }

/* ---------- Alerts ---------- */
.alert {
    padding: 13px 15px;
    border-radius: var(--radius-sm);
    margin-bottom: 16px;
    font-size: .94rem;
    border: 1px solid transparent;
}
.alert-success { background: var(--green-light); color: var(--green-dark); border-color: #cfe3d8; }
.alert-warning { background: var(--amber-light); color: var(--amber); border-color: #fcd9a0; }
.alert-error   { background: var(--red-light);   color: var(--red);   border-color: #f6b9b9; }
.alert-info    { background: var(--blue-light);  color: var(--blue);  border-color: #bfd3fb; }

/* ---------- Steps ---------- */
.steps { display: grid; gap: 14px; }
.step { display: flex; gap: 13px; align-items: flex-start; }
.step-num {
    flex: 0 0 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--green);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: .9rem;
}
.step-body h3 { margin-bottom: 3px; font-size: 1rem; }
.step-body p  { margin: 0; font-size: .92rem; color: var(--ink-soft); }

/* ---------- Timeline ---------- */
.timeline { list-style: none; margin: 0; padding: 0; }
.timeline li {
    position: relative;
    padding: 0 0 20px 28px;
    border-left: 2px solid var(--line);
}
.timeline li:last-child { border-left-color: transparent; padding-bottom: 0; }
.timeline li::before {
    content: "";
    position: absolute;
    left: -7px; top: 3px;
    width: 12px; height: 12px;
    border-radius: 50%;
    background: #fff;
    border: 2px solid var(--line);
}
.timeline li.done { border-left-color: var(--green); }
.timeline li.done::before { background: var(--green); border-color: var(--green); }
.timeline .when { font-size: .82rem; color: var(--ink-faint); }

/* ---------- Book hero ---------- */
.book-hero { display: grid; gap: 18px; }
.book-cover {
    width: 150px;
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-lg);
    margin: 0 auto;
}
.price-headline {
    font-size: 1.7rem;
    font-weight: 700;
    color: var(--green-dark);
    font-variant-numeric: tabular-nums;
}
.price-mrp { text-decoration: line-through; color: var(--ink-faint); font-size: 1rem; font-weight: 400; }

/* ---------- Header and form fit ---------- */
/* The tagline wraps to two lines on a narrow phone, which makes the header
   taller than the first thing anyone came to read. One line, ellipsis if it
   does not fit — the full text is still in the page for screen readers. */
.brand-sub {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
@media (min-width: 480px) {
    .brand-sub { white-space: normal; }
}

/* Two selects side by side inside the ~420px desktop form column leaves the
   Kannada placeholders clipped mid-word. The pair only fits two-up in the
   full-width phone layout, so stack it in the aside. */
@media (min-width: 1024px) {
    .landing-aside .field-pair { grid-template-columns: 1fr; }
}

/* A <select> clips its text with no ellipsis and no warning. Give the value
   room by allowing the control to shrink to its container rather than to its
   longest option. */
select { max-width: 100%; text-overflow: ellipsis; }

/* ---------- Other titles (the shop window) ---------- */
/* auto-fill rather than a fixed column count, so the grid adapts as the
   catalogue grows without needing a new breakpoint per title. */
.title-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 16px;
    margin: 14px 0 12px;
}
.title-card { min-width: 0; }
.title-cover {
    width: 100%;
    max-width: 140px;
    aspect-ratio: 3 / 4;
    object-fit: cover;
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow);
    background: var(--green-light);
}
.title-cover-empty {
    display: grid;
    place-items: center;
    color: var(--green);
    font-size: 2rem;
    font-weight: 700;
}
.title-body h3 { font-size: .98rem; margin: 8px 0 2px; }
.title-body p  { margin: 0 0 2px; }

/* ---------- Brand mark ---------- */
.brand-link { display: flex; align-items: center; gap: 10px; text-decoration: none; }

/* The mark is constrained THREE ways on purpose.
   width fixes its size, max-height stops it ever driving the header's height,
   and flex-shrink:0 keeps it from being squashed by a long organisation name.
   The SVG file also carries its own width/height attributes, so even with this
   stylesheet missing entirely the logo stays small instead of filling the
   page. */
.brand-mark {
    flex: 0 0 auto;
    width: 34px;
    max-height: 40px;
    color: #fff;
    overflow: hidden;
}
.brand-mark svg {
    width: 100%;
    height: auto;
    max-height: 40px;
    display: block;
}
.brand-text { min-width: 0; }

@media (min-width: 1024px) {
    .brand-mark { width: 42px; max-height: 48px; }
    .brand-mark svg { max-height: 48px; }
}

/* ---------- Quantity by edition ---------- */
/* Two boxes side by side even on the narrowest phone: they are short numeric
   fields, and stacking them makes the pair read as two unrelated questions
   rather than one "how many of each". */
.qty-editions { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.qty-edition label {
    display: block;
    font-size: .88rem;
    font-weight: 600;
    color: var(--ink-soft);
    margin-bottom: 4px;
}
.qty-edition input { width: 100%; }
.qty-total {
    margin-top: 10px;
    padding: 8px 12px;
    background: var(--green-light);
    border-radius: var(--radius-sm);
    font-size: .95rem;
}
.qty-total strong { font-variant-numeric: tabular-nums; }

/* ---------- Testimonials ---------- */
.testimonial {
    border-left: 3px solid var(--green);
    padding: 4px 0 4px 14px;
    margin-bottom: 16px;
}
.testimonial p { margin: 0 0 5px; font-style: italic; }
.testimonial cite { font-style: normal; font-size: .85rem; color: var(--ink-faint); }

/* ---------- FAQ ---------- */
details.faq {
    border-bottom: 1px solid var(--line);
    padding: 13px 0;
}
details.faq summary {
    font-weight: 620;
    cursor: pointer;
    list-style: none;
    min-height: 30px;
    padding-right: 26px;
    position: relative;
}
details.faq summary::-webkit-details-marker { display: none; }
details.faq summary::after {
    content: "+";
    position: absolute;
    right: 4px; top: 0;
    font-size: 1.3rem;
    color: var(--green);
    line-height: 1;
}
details.faq[open] summary::after { content: "−"; }
details.faq .faq-body { padding-top: 8px; color: var(--ink-soft); font-size: .95rem; }

/* ---------- Prose (policy pages, admin-authored HTML) ---------- */
.prose h2 { margin-top: 1.5em; }
.prose h3 { margin-top: 1.3em; font-size: 1rem; }
.prose ul, .prose ol { padding-left: 22px; }
.prose li { margin-bottom: .4em; }
.prose table { width: 100%; border-collapse: collapse; margin: 1em 0; }
.prose th, .prose td { border: 1px solid var(--line); padding: 8px 10px; text-align: left; }

/* ---------- Footer ---------- */
.site-footer {
    background: #fff;
    border-top: 1px solid var(--line);
    padding: 26px 0;
    margin-top: 36px;
    font-size: .88rem;
    color: var(--ink-soft);
}
.footer-links {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 20px;
    margin-bottom: 16px;
}
.footer-links a { color: var(--ink-soft); text-decoration: none; }
.footer-links a:hover { color: var(--green); text-decoration: underline; }

/* ---------- QR / UPI ---------- */
.upi-box { text-align: center; }
.upi-id {
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 1.05rem;
    background: #f1f2f4;
    padding: 11px 14px;
    border-radius: var(--radius-sm);
    word-break: break-all;
    user-select: all;
}
.upi-qr { max-width: 230px; margin: 16px auto; }

/* ---------- Spinner ---------- */
.spinner {
    display: inline-block;
    width: 17px; height: 17px;
    border: 2.5px solid rgba(255,255,255,.35);
    border-top-color: #fff;
    border-radius: 50%;
    animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- Wider screens ---------- */
@media (min-width: 640px) {
    h1 { font-size: 1.9rem; }
    .card { padding: 24px; }
    .section { padding: 36px 0; }
    .slots { grid-template-columns: 1fr; }
    /* Only when a cover image actually exists. Without this guard the text
       block becomes the first grid item and gets squeezed into the 170px
       column — which is what every fresh install looked like. */
    .book-hero.has-cover { grid-template-columns: 170px 1fr; align-items: start; }
    .book-cover { margin: 0; }
    .field-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
}

/* =============================================================================
   DESKTOP
   =============================================================================
   Everything above is the phone layout, and it is the one that matters most —
   nearly every trainer arrives from a WhatsApp link. But the admin works from a
   laptop, and a phone column stranded down the middle of a 1440px screen looks
   unfinished and reads badly: a paragraph 1200px wide runs to 170 characters a
   line, roughly twice the length the eye tracks comfortably.

   So: cap the measure, then use the extra width for something useful rather
   than stretching what is already fine.
   ========================================================================== */

/* Prose never gets wider than about 68 characters, whatever the container.
   `ch` is the width of "0" in the current font, so this tracks the font size
   instead of guessing in pixels. */
.prose p, .prose li, .card > p, .step-body p, .alert {
    max-width: 68ch;
}
.center .prose p, .center > p { margin-left: auto; margin-right: auto; }

@media (min-width: 1024px) {
    /* Two columns: the book on the left, the booking form on the right where
       it is visible without scrolling. On phones .landing-grid is just a plain
       block and this never applies. */
    .landing-grid {
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(360px, 420px);
        gap: 24px;
        align-items: start;
    }
    .wrap { max-width: 1120px; }

    /* The form follows you down the page instead of scrolling away.
       max-height + overflow keeps a long form usable on a short laptop screen
       rather than clipping its submit button off the bottom. */
    .landing-aside > .card {
        position: sticky;
        top: 16px;
        max-height: calc(100vh - 32px);
        overflow-y: auto;
    }

    h1 { font-size: 2.1rem; }
    h2 { font-size: 1.4rem; }
    .card { padding: 26px 24px; }
    .section { padding: 40px 0; }
}

@media (min-width: 1440px) {
    .wrap { max-width: 1200px; }
}

/* A sticky panel is wrong when the user has asked for less motion, and wrong
   on a short screen where it would cover the page. */
@media (prefers-reduced-motion: reduce) {
    .landing-aside > .card { position: static; max-height: none; }
}
@media (max-height: 700px) {
    .landing-aside > .card { position: static; max-height: none; }
}

/* ---------- Print (receipts, labels) ---------- */
@media print {
    .site-header, .site-footer, .banner, .btn, .no-print { display: none !important; }
    body { background: #fff; font-size: 12pt; }
    .card { border: none; box-shadow: none; padding: 0; }
}

/* ---------- Respect reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        transition-duration: .01ms !important;
    }
}

/* =============================================================================
 *  BOOK PICKER — release 2.1
 *
 *  Shown only when more than one title is on sale. It is a list of links, not a
 *  <select>: a trainer choosing between two books wants to see both covers and
 *  both prices at once, and on a phone a dropdown hides exactly that.
 * ========================================================================== */
.book-picker { padding-bottom: 6px; }

.picker-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 10px;
}

.picker {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    padding: 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--card);
    text-decoration: none;
    color: inherit;
    transition: border-color .15s, box-shadow .15s;
    min-height: 44px;                 /* a thumb target, like every other tap */
}
.picker:hover,
.picker:focus-visible { border-color: var(--green); box-shadow: var(--shadow); }

.picker-on {
    border-color: var(--green);
    background: var(--green-light);
    box-shadow: inset 0 0 0 1px var(--green);
}

.picker-cover {
    width: 64px; height: 90px;
    object-fit: cover;
    border-radius: var(--radius-sm);
    background: #eef1f4;
    flex-shrink: 0;
}
.picker-cover-blank {
    display: grid; place-items: center;
    font-size: 26px;
}

.picker-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.picker-title { font-size: 1rem; line-height: 1.3; }
.picker-price { color: var(--green); font-weight: 650; font-size: .92rem; }

.picker-editions { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 2px; }
.picker-editions .chip {
    font-size: .72rem;
    border: 1px solid var(--line);
    border-radius: 999px;
    padding: 1px 8px;
    color: var(--ink-soft);
    background: var(--bg);
}

.picker-live { font-size: .8rem; color: var(--green); font-weight: 600; min-height: 1em; }

/* An empty live line must not leave a gap where a sentence will appear. */
.live-copies { color: var(--green); }
.live-copies.is-empty:empty { display: none; }

/* A number that changes while you are reading it deserves to be noticed once,
   and then left alone. Suppressed under prefers-reduced-motion by live.js. */
@keyframes live-bump {
    0%   { transform: none; }
    30%  { transform: translateY(-2px) scale(1.03); }
    100% { transform: none; }
}
.live-bump { animation: live-bump .45s ease-out; display: inline-block; }

@media (min-width: 620px) {
    .picker-grid { grid-template-columns: 1fr 1fr; }
}

/* A UPI deep link only does something on a device with a payment app on it.
   Shown on phones, hidden on the desktop where tapping it does nothing. */
.only-mobile { display: block; }
@media (min-width: 720px) { .only-mobile { display: none; } }

/* "Yes, book again" — only rendered after the server has told them a booking
   already exists, so it needs to look like a decision, not a default. */
.confirm-dup { border: 1px solid var(--amber); background: var(--amber-light); border-radius: var(--radius); padding: 12px; }
.confirm-dup .checkline { display: flex; gap: 10px; align-items: flex-start; margin: 0; cursor: pointer; }
.confirm-dup input[type="checkbox"] { width: 21px; height: 21px; accent-color: var(--green); flex-shrink: 0; margin-top: 1px; }

/* =============================================================================
   THE PUBLISHER WEBSITE (4.0)

   Added for index.php, book.php and the banner module. Everything below is
   mobile-first: the grids are one column by default and only become two or
   three where there is genuinely room, because the overwhelming majority of
   visitors arrive on a 360px Android screen from a WhatsApp link.
   ========================================================================== */

/* ---------- Hero ---------- */
.hero {
    background: linear-gradient(160deg, var(--green-light) 0%, #fff 70%);
    border-bottom: 1px solid var(--line);
    padding: 26px 0 30px;
}
.hero-inner { display: grid; gap: 22px; }
.hero-title { font-size: 1.7rem; line-height: 1.25; margin: 0 0 10px; }
.hero-sub   { font-size: 1.02rem; color: var(--muted); margin: 0 0 18px; }
.hero-cta   { display: flex; flex-wrap: wrap; gap: 10px; }
.hero-cta .btn { flex: 1 1 auto; }
.hero-note  { font-size: .84rem; color: var(--muted); margin: 10px 0 0; }
.hero-stats {
    display: flex; flex-wrap: wrap; gap: 18px;
    margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line);
    font-size: .88rem; color: var(--muted);
}
.hero-stats strong { color: var(--green-dark); font-size: 1.15rem; }
.hero-art img {
    width: 100%; max-width: 320px; height: auto; display: block; margin: 0 auto;
    border-radius: var(--radius); box-shadow: 0 6px 24px rgba(0,0,0,.13);
}
@media (min-width: 820px) {
    .hero { padding: 44px 0 48px; }
    .hero-inner { grid-template-columns: 1.25fr .75fr; align-items: center; gap: 40px; }
    .hero-title { font-size: 2.3rem; }
    .hero-cta .btn { flex: 0 0 auto; }
}

/* ---------- Scheduled strip advert ---------- */
.ad-strip { background: var(--green-dark); color: #fff; }
.ad-strip-inner {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
    gap: 12px; padding: 13px 0;
}
.ad-strip strong { display: block; }
.ad-strip-sub { font-size: .87rem; opacity: .9; }
.ad-strip .btn-primary { background: #fff; color: var(--green-dark); border-color: #fff; }

/* ---------- Section headings ---------- */
.section-title {
    font-size: 1.22rem; margin: 30px 0 14px;
    padding-bottom: 8px; border-bottom: 2px solid var(--green-light);
}
.section-title:first-child { margin-top: 0; }

/* ---------- Book grid ---------- */
.book-grid { display: grid; gap: 16px; grid-template-columns: 1fr; }
@media (min-width: 560px) { .book-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 900px) { .book-grid { grid-template-columns: repeat(3, 1fr); } }

.book-card {
    display: flex; flex-direction: column;
    background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
    overflow: hidden;
}
.book-card-cover {
    display: block; background: var(--green-light);
    aspect-ratio: 3 / 4; overflow: hidden;
}
.book-card-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.book-card-nocover {
    display: flex; align-items: center; justify-content: center;
    width: 100%; height: 100%; font-size: 3rem;
}
.book-card-body { padding: 13px 14px 15px; display: flex; flex-direction: column; gap: 7px; flex: 1; }
.book-card-cat  { font-size: .74rem; text-transform: uppercase; letter-spacing: .4px; color: var(--muted); }
.book-card-title { font-size: 1.02rem; margin: 0; line-height: 1.3; }
.book-card-title a { color: inherit; text-decoration: none; }
.book-card-title a:hover { color: var(--green-dark); }
.book-card-hl   { font-size: .87rem; color: var(--muted); margin: 0; }
.book-card-exp  { font-size: .85rem; margin: 0; }
.book-card-foot {
    margin-top: auto; padding-top: 10px;
    display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap;
}
.book-card-price { font-weight: 700; color: var(--green-dark); }

/* ---------- Book page ---------- */
.crumb { font-size: .88rem; margin: 0 0 14px; }
.book-hero { display: grid; gap: 18px; margin-bottom: 20px; }
.book-hero-cover {
    background: var(--green-light); border-radius: var(--radius); overflow: hidden;
    max-width: 260px; aspect-ratio: 3 / 4;
}
.book-hero-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.book-price-line { font-size: 1.15rem; margin: 0 0 14px; }
.book-price-line .strike { text-decoration: line-through; color: var(--muted); font-size: .9rem; margin-left: 8px; }
@media (min-width: 720px) {
    .book-hero { grid-template-columns: 260px 1fr; gap: 28px; align-items: start; }
}

/* ---------- Prose and quotes ---------- */
.prose { line-height: 1.7; }
.pub-note {
    margin: 16px 0 0; padding: 12px 16px;
    border-left: 3px solid var(--green); background: var(--green-light);
    border-radius: 0 var(--radius) var(--radius) 0; font-style: italic;
}
.quote-grid { display: grid; gap: 14px; grid-template-columns: 1fr; }
@media (min-width: 700px) { .quote-grid { grid-template-columns: 1fr 1fr; } }
.quote {
    margin: 0; padding: 16px;
    background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
}
.quote blockquote { margin: 0 0 10px; line-height: 1.6; }
.quote figcaption { font-size: .87rem; font-weight: 600; }

.cta-block { background: var(--green-light); border-color: var(--green); }

/* ---------- Pricing table on the book page ---------- */
.tier-table { width: 100%; border-collapse: collapse; }
.tier-table th, .tier-table td { padding: 9px 4px; border-bottom: 1px solid var(--line); text-align: left; }
.tier-table th { font-size: .82rem; text-transform: uppercase; letter-spacing: .3px; color: var(--muted); }
.tier-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.tier-table tr:last-child td { border-bottom: none; }

/* A card with no cover uploaded yet. Without this the 3/4 aspect ratio makes a
   full-width phone card about 480px of empty green before any text appears. */
.book-card-cover:not(:has(img)) { aspect-ratio: auto; min-height: 130px; }
.book-card-nocover { min-height: 130px; opacity: .45; }

/* =============================================================================
   4.1 — DEPTH, MOTION, AND THE SAMPLE READER

   The brief was "ultra modern, animated, 3D". The audience is a low-end Android
   phone on patchy mobile data in a Karnataka taluk. Both are honoured here by
   spending the budget on things that are cheap for a phone to draw:

     · layered shadows and a lifted press state, not perspective transforms
     · transform and opacity only, which the compositor handles without
       repainting; never animating width, height, top or left
     · reveal-on-scroll driven by IntersectionObserver, not a scroll handler
     · every one of them switched off under prefers-reduced-motion

   The result reads as current on a good phone and still paints in one frame on
   a cheap one. A rotating 3D cover would look spectacular in a demo and stutter
   for most of the people this site is for.
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {
    .btn, .book-card, .quote, .stat { transition: transform .16s ease, box-shadow .16s ease; }
    .btn:hover        { transform: translateY(-1px); box-shadow: 0 4px 14px rgba(16,24,40,.14); }
    .btn:active       { transform: translateY(1px);  box-shadow: 0 1px 3px rgba(16,24,40,.14); }
    .book-card:hover  { transform: translateY(-3px); box-shadow: 0 10px 28px rgba(16,24,40,.13); }

    /* Sections arrive as you reach them. `.reveal` is added by the small script
       in the footer; without JS everything is simply visible, which is why the
       visible state is the default and the hidden one is opt-in. */
    .reveal { opacity: 0; transform: translateY(14px); }
    .reveal.in { opacity: 1; transform: none; transition: opacity .45s ease, transform .45s ease; }
}

/* A quieter, deeper surface treatment across the site. */
.card       { box-shadow: 0 1px 2px rgba(16,24,40,.04), 0 4px 16px rgba(16,24,40,.06); }
.book-card  { box-shadow: 0 1px 2px rgba(16,24,40,.05), 0 4px 14px rgba(16,24,40,.07); }
.btn-primary {
    background: linear-gradient(180deg, #1f6d49 0%, var(--green) 55%, var(--green-dark) 100%);
    box-shadow: 0 1px 2px rgba(16,24,40,.16), inset 0 1px 0 rgba(255,255,255,.14);
}
.btn-secondary { box-shadow: 0 1px 2px rgba(16,24,40,.06); }

/* ---------- The sample reader ---------- */
.reader-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; margin-bottom: 12px;
}
.reader {
    position: relative;
    background: #20262e;
    border-radius: var(--radius);
    padding: 14px 10px;
    margin-bottom: 12px;
}
.reader-stage {
    display: flex; justify-content: center; gap: 0;
    perspective: 1400px;               /* only used for the page-turn tilt */
}
.reader-page {
    background: #fff;
    min-height: 220px;
    max-width: 100%;
    box-shadow: 0 8px 26px rgba(0,0,0,.4);
    display: flex; align-items: center; justify-content: center;
    overflow: hidden;
}
.reader-page img { display: block; width: 100%; height: auto; user-select: none; -webkit-user-drag: none; }

/* The spine. Only when two pages are actually open. */
.reader-stage.is-spread .reader-page      { width: 50%; }
.reader-stage.is-spread .reader-page:first-child { border-right: 1px solid rgba(0,0,0,.18); }
.reader-stage:not(.is-spread) .reader-page-r { display: none; }

@media (prefers-reduced-motion: no-preference) {
    .reader-stage.turning .reader-page { animation: pageturn .28s ease; }
    @keyframes pageturn {
        from { transform: rotateY(-6deg) scale(.985); opacity: .55; }
        to   { transform: none;                       opacity: 1;   }
    }
}

.reader-spinner {
    width: 26px; height: 26px; border-radius: 50%;
    border: 3px solid var(--line); border-top-color: var(--green);
    animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .reader-spinner { animation: none; } }

.reader-nav {
    position: absolute; top: 50%; transform: translateY(-50%);
    width: 44px; height: 64px;
    border: none; border-radius: 8px;
    background: rgba(255,255,255,.16); color: #fff;
    font-size: 1.8rem; line-height: 1; cursor: pointer;
}
.reader-nav:hover { background: rgba(255,255,255,.28); }
.reader-prev { left: 2px; }
.reader-next { right: 2px; }

/* The controls under the reader.
   -----------------------------------------------------------------------------
   This was a flex row of [Previous] [slider] [Next], and on a 360px phone in
   Kannada — where "Previous" is ಹಿಂದಿನದು and buttons do not wrap — it pushed
   32px off the right edge of the screen. Horizontal scroll on the one page
   whose entire job is to be read comfortably.

   A grid fixes it by construction rather than by tuning: on a phone the slider
   takes a row of its own and the two buttons split the one below, so neither
   can ever be wider than half the screen. Above 560px it becomes the row it
   was always meant to be. */
.reader-foot {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: center;
    gap: 10px;
    margin-bottom: 16px;
}
.reader-foot .btn { min-width: 0; padding-left: 12px; padding-right: 12px; }
.reader-foot input[type="range"] {
    grid-column: 1 / -1;
    order: -1;                     /* slider above the buttons, under the book */
    min-width: 0;
    min-height: 44px;
    accent-color: var(--green);
}

@media (min-width: 560px) {
    .reader-foot { grid-template-columns: auto 1fr auto; }
    .reader-foot input[type="range"] { grid-column: auto; order: 0; }
}

/* ---------- Answer keys on the book page ---------- */
.key-row {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--line);
}
.key-row:last-child { border-bottom: none; }
.key-row .key-meta { font-size: .82rem; color: var(--ink-faint); }

/* =============================================================================
   NAVIGATION (4.1)
   -----------------------------------------------------------------------------
   Written twice on purpose, and the order matters.

   The DEFAULT here — the rules outside any `html.js` selector — is a plain row
   of links in the header. That is what a browser with JavaScript turned off
   gets, and it works: every destination is reachable, nothing is hidden behind
   a button that cannot open.

   The DRAWER is layered on top, and only under `html.js`, because a drawer
   that cannot be opened is worse than no drawer. The flag is set in <head>
   before paint, so a phone never sees the plain list flash and collapse.

   The whole thing animates with transform and opacity only. A menu that
   repaints layout as it slides is the single easiest way to make a ₹6,000
   Android phone feel broken.
   ========================================================================== */

.site-nav-inner {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: wrap;
}

.nav-link {
    color: #fff;
    text-decoration: none;
    font-size: .92rem;
    font-weight: 550;
    padding: 9px 13px;
    border-radius: 9px;
    min-height: 40px;
    display: inline-flex;
    align-items: center;
    position: relative;
    transition: background-color .18s ease, transform .18s ease;
}
.nav-link:hover   { background: rgba(255,255,255,.12); }
.nav-link:active  { transform: translateY(1px); }

/* The current page is underlined rather than filled: a filled pill in a row of
   plain links reads as "press me", which is the opposite of what it means. */
.nav-link.is-here::after {
    content: "";
    position: absolute;
    left: 13px; right: 13px; bottom: 4px;
    height: 2px;
    background: var(--gold, #d4a017);
    border-radius: 2px;
}

/* The hamburger. Hidden entirely until the drawer exists AND the screen is
   narrow — otherwise it sits in the corner of a desktop doing nothing. */
.nav-toggle {
    display: none;
    width: 44px; height: 44px;
    flex: 0 0 auto;
    border: 1px solid rgba(255,255,255,.4);
    border-radius: 11px;
    background: rgba(255,255,255,.08);
    color: #fff;
    cursor: pointer;
    padding: 0;
    align-items: center;
    justify-content: center;
}
.nav-bars { display: block; width: 20px; }
.nav-bars span {
    display: block;
    height: 2px;
    background: #fff;
    border-radius: 2px;
    transition: transform .22s ease, opacity .18s ease;
}
.nav-bars span + span { margin-top: 5px; }

.nav-scrim {
    position: fixed;
    inset: 0;
    background: rgba(12, 30, 22, .55);
    z-index: 45;
    opacity: 0;
    transition: opacity .22s ease;
}
.nav-scrim.is-open { opacity: 1; }

/* ---------------------------------------------------------------------------
   Drawer mode: script present, screen narrow.
   -------------------------------------------------------------------------- */
@media (max-width: 899px) {

    html.js .nav-toggle { display: inline-flex; }

    html.js .site-nav {
        position: fixed;
        top: 0; right: 0; bottom: 0;
        width: min(300px, 84vw);
        background: var(--green-dark, #123b2b);
        z-index: 50;
        padding: 68px 16px 24px;
        overflow-y: auto;
        transform: translateX(100%);
        transition: transform .26s cubic-bezier(.22,.61,.36,1);
        box-shadow: -18px 0 40px rgba(0,0,0,.28);
        /* Keeps the drawer clear of a notch or a gesture bar. */
        padding-bottom: calc(24px + env(safe-area-inset-bottom, 0px));
    }

    html.js .site-nav.is-open { transform: translateX(0); }

    html.js .site-nav-inner {
        flex-direction: column;
        align-items: stretch;
        gap: 2px;
    }

    html.js .nav-link {
        font-size: 1rem;
        padding: 14px 14px;
        min-height: 48px;
        border-bottom: 1px solid rgba(255,255,255,.08);
        border-radius: 0;
    }
    html.js .nav-link.is-here::after { left: 0; right: auto; width: 3px; top: 10px; bottom: 10px; height: auto; }

    html.js .site-nav .lang-toggle { margin-top: 16px; justify-content: center; }

    /* Open state turns the bars into a cross, so the same button closes it. */
    html.js .nav-toggle[aria-expanded="true"] .nav-bars span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
    html.js .nav-toggle[aria-expanded="true"] .nav-bars span:nth-child(2) { opacity: 0; }
    html.js .nav-toggle[aria-expanded="true"] .nav-bars span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

    /* The button has to sit above the drawer it opens, or the cross that
       closes it slides underneath the panel and cannot be pressed. */
    html.js .nav-toggle { position: relative; z-index: 55; }

    /* With no script, the plain list wraps under the brand rather than
       squeezing it. */
    html:not(.js) .site-nav { flex-basis: 100%; margin-top: 8px; }
}

@media (prefers-reduced-motion: reduce) {
    .site-nav, .nav-scrim, .nav-bars span, .nav-link { transition: none !important; }
}
