@font-face{
  font-family:Lexend;
  src:url("/assets/fonts/LexendVariable-latin.woff2") format("woff2");
  font-style:normal;
  font-weight:300 800;
  font-display:swap;
  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;
}
:root{
  --font-ui:var(--vq-font);
  --font-editorial:Georgia,"Times New Roman",serif;
}

html{
  font-family:var(--font-ui);
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  text-rendering:optimizeLegibility;
}

body{
  font-family:var(--font-ui)!important;
  font-optical-sizing:auto;
  font-synthesis:none;
}

button,input,select,textarea{font-family:inherit}
[hidden]{display:none!important}

[data-progress],
[data-percentage]{
  font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum" 1;
}

/* Shared components: one look everywhere — ink outlines on graph paper. */
:root{
  --vq-graph-paper:linear-gradient(var(--vq-grid) 1px,transparent 1px),linear-gradient(90deg,var(--vq-grid) 1px,transparent 1px);
}

/* Learner state chip. Shape carries the state, so it reads without colour:
   Mastered = solid ink, Learning = dashed outline, Not Seen = faint outline. */
.vq-chip{display:inline-flex;align-items:center;justify-content:center;gap:var(--vq-space-1);border:var(--vq-border);border-radius:var(--vq-radius-pill);padding:2px var(--vq-space-3);background:transparent;color:var(--vq-ink);font:var(--vq-weight-bold) var(--vq-text-xs)/1.3 var(--vq-font);white-space:nowrap}
.vq-chip.is-mastered{background:var(--vq-ink);color:var(--vq-on-ink)}
.vq-chip.is-learning{border-style:dashed}
.vq-chip.is-not-seen{border-color:var(--vq-ink-subtle);color:var(--vq-ink-muted)}

/* Progress bar: <span class="vq-progress" style="--value:47%;--target:80%"><i></i></span>.
   An outlined track with a blue fill; the tick marks the mastery target. */
.vq-progress{position:relative;display:block;box-sizing:border-box;height:12px;overflow:hidden;border:var(--vq-border);border-radius:6px;background:var(--vq-paper)}
.vq-progress>i{display:block;width:var(--value,0%);height:100%;background:var(--vq-accent);transition:width .3s ease}
.vq-progress::after{content:"";position:absolute;top:0;bottom:0;left:var(--target,80%);width:2px;background:var(--vq-ink);opacity:.35}
.vq-progress--thin{height:8px;border-radius:4px}
@media(prefers-reduced-motion:reduce){.vq-progress>i{transition:none}}

/* Install as an app (app-shell.js). Install controls disappear inside the installed app. */
html[data-display-mode="standalone"] [data-install-app],
html[data-display-mode="standalone"] [data-install-card]{display:none}
.vq-install-help{width:min(100vw - 2 * var(--vq-gutter),400px);border:var(--vq-border);border-radius:var(--vq-radius-lg);padding:var(--vq-space-5);background:var(--vq-paper);color:var(--vq-ink);font-family:var(--vq-font)}
.vq-install-help::backdrop{background:var(--vq-scrim)}
.vq-install-help h2{margin:0 0 var(--vq-space-2);font:var(--vq-weight-bold) var(--vq-text-lg)/1.2 var(--vq-font);letter-spacing:var(--vq-tracking-tight)}
.vq-install-help p{margin:0 0 var(--vq-space-3);color:var(--vq-ink-muted);font:var(--vq-weight-medium) var(--vq-text-sm)/1.45 var(--vq-font)}
.vq-install-help ol{display:grid;gap:var(--vq-space-2);margin:0 0 var(--vq-space-5);padding-left:var(--vq-space-5);font:var(--vq-weight-medium) var(--vq-text-sm)/1.45 var(--vq-font)}
.vq-install-help button{width:100%;min-height:var(--vq-tap);border:var(--vq-border);border-radius:var(--vq-radius-sm);background:var(--vq-ink);color:var(--vq-on-ink);font:var(--vq-weight-bold) var(--vq-text-sm)/1 var(--vq-font);cursor:pointer}
.vq-install-help button:focus-visible{outline:3px solid var(--vq-focus);outline-offset:2px}

/* The screen's main button (one per screen), on every page (#101: moved here from app-shell.css, which the
   student pages don't load, for the install screen's button). */
.primary-action{display:inline-flex;align-items:center;justify-content:center;gap:9px;min-height:var(--vq-button-height);padding:15px 18px;border:var(--vq-border);border-radius:var(--vq-radius-sm);background:var(--vq-ink);color:var(--vq-on-ink);font:var(--vq-weight-bold) 1rem/1 var(--vq-font);text-decoration:none;cursor:pointer;transition:background-color .18s ease,transform .18s ease}
.primary-action svg{width:18px;height:18px;stroke-width:2.4}
.primary-action:hover{border-color:var(--vq-accent);background:var(--vq-accent)}
.primary-action:active{transform:scale(.985)}
/* The same button, stepped back when it isn't the screen's main job (one bold button per screen). */
.primary-action.is-quiet{background:var(--vq-surface);color:var(--vq-ink)}
.primary-action.is-quiet:hover{border-color:var(--vq-accent);background:var(--vq-surface);color:var(--vq-accent)}

/* #101: in a browser tab, a gated page shows only "Vigyaniq works as an app" (install-gate.js). */
html[data-display-mode="browser"] body[data-install-gate="always"] .app-page-content>:not(.vq-install-gate),
html[data-display-mode="browser"][data-install-ios] body[data-install-gate="ios"] .app-page-content>:not(.vq-install-gate),
html[data-install-gate-on] .app-page-content>:not(.vq-install-gate),
html[data-install-gate-on] .app-tabbar,
/* #102: no UPI ID, no practice: the child's phone shows only "Ask your parent to add your UPI ID" (upi-gate.js). */
html[data-upi-gate-on] .app-page-content>:not(.vq-upi-gate):not(.vq-install-gate),
html[data-upi-gate-on] .app-tabbar{display:none}
.vq-install-gate,.vq-upi-gate{display:grid;align-content:center;gap:var(--vq-space-4);width:min(100%,calc(440px + 2 * var(--vq-gutter)));min-height:100%;margin:0 auto;padding:var(--vq-space-5) var(--vq-gutter);color:var(--vq-ink);font-family:var(--vq-font)}
.vq-install-gate h1,.vq-upi-gate h1{margin:0;font:var(--vq-weight-bold) var(--vq-text-hero)/1.15 var(--vq-font);letter-spacing:var(--vq-tracking-tight)}
.vq-install-gate-lead{margin:0;color:var(--vq-ink-muted);font:var(--vq-weight-medium) var(--vq-text-md)/1.45 var(--vq-font)}
.vq-install-gate-steps{display:grid;gap:var(--vq-space-3);margin:0;padding:0;list-style:none}
.vq-install-gate-steps li{display:grid;grid-template-columns:auto 1fr;align-items:center;gap:var(--vq-space-3);padding:var(--vq-space-3) var(--vq-space-4);border:var(--vq-border);border-radius:var(--vq-radius-md);background:var(--vq-surface);font:var(--vq-weight-medium) var(--vq-text-sm)/1.4 var(--vq-font)}
.vq-install-gate-steps svg{width:24px;height:24px;color:var(--vq-accent)}
.vq-install-gate .primary-action,.vq-upi-gate .primary-action{width:100%}

/* Toast (toast.js, owner 2026-10-10): one app-wide card floating over the page, a coloured icon per type, the message
   and an optional text action. Bottom: above the tab bar (toast.js measures it into --vq-toast-offset) or the safe
   area; top: under the header. The text wraps at any font size; the action drops under the message when it must. */
.vq-toast{position:fixed;left:50%;z-index:1100;box-sizing:border-box;display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:var(--vq-space-2) var(--vq-space-3);width:min(calc(100vw - 2 * var(--vq-gutter)),440px);margin:0;padding:var(--vq-space-3) var(--vq-space-4);border:var(--vq-border-width) solid var(--vq-line);border-radius:var(--vq-radius-lg);background:var(--vq-surface-muted);box-shadow:var(--vq-shadow-float);color:var(--vq-ink);font-family:var(--vq-font);cursor:default;opacity:0;transform:translate(-50%,var(--vq-toast-from));transition:opacity .2s ease-out,transform .25s ease-out;--vq-toast-from:var(--vq-space-4)}
.vq-toast[data-position=bottom]{bottom:calc(var(--vq-space-3) + env(safe-area-inset-bottom))}
.vq-toast[data-position=bottom][data-over-tabbar]{bottom:calc(var(--vq-toast-offset) + var(--vq-space-3))}
.vq-toast[data-position=top]{top:calc(var(--vq-space-3) + env(safe-area-inset-top));--vq-toast-from:calc(-1 * var(--vq-space-4))}
.vq-toast[data-position=top][data-under-header]{top:calc(var(--vq-toast-offset) + var(--vq-space-2))}
.vq-toast[data-state=shown]{opacity:1;transform:translate(-50%,0)}
.vq-toast[data-state=leaving]{opacity:0;transform:translate(-50%,var(--vq-toast-from))}
.vq-toast-main{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:start;gap:var(--vq-space-3);flex:1 1 14rem;min-width:0}
.vq-toast-icon{display:block;width:1.5rem;height:1.5rem;color:var(--vq-toast-colour)}
.vq-toast-icon:empty{width:.75rem;height:.75rem;margin:.375rem;border-radius:var(--vq-radius-pill);background:var(--vq-toast-colour)}
.vq-toast-message{margin:0;padding-top:.125rem;font:var(--vq-weight-medium) var(--vq-text-sm)/1.45 var(--vq-font);overflow-wrap:anywhere}
.vq-toast-action{flex:0 0 auto;min-height:var(--vq-tap);margin:calc(-1 * var(--vq-space-2)) calc(-1 * var(--vq-space-2)) calc(-1 * var(--vq-space-2)) auto;padding:0 var(--vq-space-2);border:0;border-radius:var(--vq-radius-sm);background:transparent;color:var(--vq-toast-colour);font:var(--vq-weight-bold) var(--vq-text-sm)/1.2 var(--vq-font);text-transform:uppercase;letter-spacing:.04em;cursor:pointer}
.vq-toast-action:focus-visible{outline:3px solid var(--vq-focus);outline-offset:2px}
.vq-toast[data-type=info]{--vq-toast-colour:var(--vq-accent)}
.vq-toast[data-type=success]{--vq-toast-colour:var(--vq-success)}
.vq-toast[data-type=warning]{--vq-toast-colour:var(--vq-warning)}
.vq-toast[data-type=danger]{--vq-toast-colour:var(--vq-danger)}
@media(prefers-reduced-motion:reduce){.vq-toast{transition:none;--vq-toast-from:0}}
/* End toast */
/* Cover (cover.js, owner 2026-10-10, design /lab/cover): app events over the whole app; a modal dialog (the top layer
   covers the header and tab bar too), the tokens' scrim blurred behind, a centred card in front. */
.vq-cover{box-sizing:border-box;width:min(calc(100vw - 2 * var(--vq-gutter)),22rem);max-width:none;margin:auto;padding:0;border:0;background:transparent;color:var(--vq-ink);font-family:var(--vq-font)}
.vq-cover::backdrop{background:var(--vq-scrim);backdrop-filter:blur(2px)}
.vq-cover:focus{outline:none}
.vq-cover-card{display:grid;justify-items:center;gap:var(--vq-space-3);padding:var(--vq-space-6) var(--vq-space-5) var(--vq-space-5);border:var(--vq-border);border-radius:var(--vq-radius-lg);background:var(--vq-surface);box-shadow:var(--vq-shadow-float);text-align:center}
.vq-cover-icon{display:grid;place-items:center;width:72px;height:72px;margin-bottom:var(--vq-space-2);border-radius:var(--vq-radius-pill);background:var(--vq-accent-soft);color:var(--vq-accent)}
.vq-cover-icon svg{width:36px;height:36px;stroke-width:2}
.vq-cover-title{margin:0;font:var(--vq-weight-bold) var(--vq-text-lg)/1.25 var(--vq-font);letter-spacing:var(--vq-tracking-tight)}
.vq-cover-message{margin:0;color:var(--vq-ink-muted);font:var(--vq-weight-medium) var(--vq-text-md)/1.45 var(--vq-font)}
.vq-cover-action{width:100%;margin-top:var(--vq-space-3)}
@media(prefers-reduced-motion:no-preference){.vq-cover[open]{animation:vq-cover-in .2s ease-out}}
@keyframes vq-cover-in{from{opacity:0;transform:scale(.96)}to{opacity:1;transform:none}}
/* End cover */
/* Read by screen readers, not shown (e.g. a chart's numbers as a table). */
.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
/* Placeholders in the shape of content still loading (#33), so nothing jumps when it arrives. */
.vq-skeleton{display:block;min-height:var(--vq-tap);border-radius:var(--vq-radius-md);background:linear-gradient(90deg,var(--vq-surface-muted) 30%,var(--vq-surface-tint) 50%,var(--vq-surface-muted) 70%) 0 0/300% 100%;animation:vq-skeleton 1.4s ease-in-out infinite}
.vq-skeleton+.vq-skeleton{margin-top:var(--vq-space-3)}
@keyframes vq-skeleton{from{background-position:100% 0}to{background-position:0 0}}
@media (prefers-reduced-motion:reduce){.vq-skeleton{animation:none}}

/* Bottom tab bar (#46; app-frame.css gives it its row): icon over a short label, the current one in ink. */
.app-tabbar{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);border-top:var(--vq-border);background:var(--vq-paper)}
.app-tabbar[hidden]{display:none}
.app-tabbar a{display:grid;justify-items:center;align-content:center;gap:2px;min-height:56px;padding:var(--vq-space-1) 0;color:var(--vq-ink-muted);font:var(--vq-weight-medium) var(--vq-text-header-xs)/1.2 var(--vq-font);text-decoration:none;-webkit-tap-highlight-color:transparent}
.app-tabbar svg{width:22px;height:22px}
.app-tabbar span{max-width:100%;padding:0 2px;text-align:center;overflow-wrap:anywhere}
.app-tabbar a[aria-current=page]{color:var(--vq-ink);font-weight:var(--vq-weight-bold)}
.app-tabbar a[aria-current=page] svg{stroke-width:2.6}
.app-tabbar a:focus-visible{outline:3px solid var(--vq-focus);outline-offset:-3px}

/* Section heading (#49): the one look for every heading of a part of a page, app-wide. No line under it; spacing
   groups the sections. The tester compares every section heading's look across screens. */
.vq-section-title{margin:0 0 var(--vq-space-3);padding:0;border:0;color:var(--vq-ink);font:var(--vq-weight-bold) var(--vq-text-lg)/1.2 var(--vq-font);letter-spacing:var(--vq-tracking-tight);text-transform:none}
/* Period tabs: the Stats tab's timeline (7 days, 30 days...) and the journey story's (#85), one control. */
.stats-tabs{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);border:var(--vq-border);border-radius:var(--vq-radius-sm);overflow:hidden}
.stats-tabs button{min-height:var(--vq-tap);border:0;background:transparent;color:var(--vq-ink);font:var(--vq-weight-medium) var(--vq-text-sm)/1.2 var(--vq-font);cursor:pointer}
.stats-tabs button+button{border-left:var(--vq-border)}
.stats-tabs button[aria-selected=true]{background:var(--vq-ink);color:var(--vq-surface);font-weight:var(--vq-weight-bold)}
/* Tabs (tabs.js; owner, 2026-10-11: Pariksha's ready cards, the standard top tab / sub-tab pattern): .vq-tabs of
   .vq-tab, the current one underlined in ink; under it an optional .vq-filter row of .vq-chip tabs, the current one
   filled. Both are role=tablist bound by VigyaniqTabs.bind; a chip's pill is smaller but its tap reaches 44px. */
.vq-tabs{display:flex;gap:var(--vq-space-2)}
.vq-tab{flex:1;min-height:var(--vq-tap);border:0;border-bottom:var(--vq-space-1) solid var(--vq-line);background:none;color:var(--vq-ink-muted);font:var(--vq-weight-bold) var(--vq-text-md)/1 var(--vq-font);cursor:pointer}
.vq-tab[aria-selected="true"]{border-bottom-color:var(--vq-ink);color:var(--vq-ink)}
.vq-filter{display:flex;flex-wrap:wrap;gap:var(--vq-space-2)}
.vq-filter .vq-chip{min-height:var(--vq-tap);margin-block:calc(var(--vq-space-1) * -1);padding:var(--vq-space-1) calc(var(--vq-space-3) + var(--vq-border-width));border:var(--vq-space-1) solid transparent;border-inline-width:0;background-clip:padding-box;box-shadow:inset 0 0 0 var(--vq-border-width) var(--vq-ink);font-size:var(--vq-text-sm);cursor:pointer}
.vq-filter .vq-chip[aria-selected="true"]{background-color:var(--vq-ink);color:var(--vq-on-ink)}
/* End tabs */
/* The app's stepper (owner, 2026-10-10: the test hand-in's, now the standard for every multi-step flow): numbered
   dots with a label; the current one in ink, the done ones green with a tick. */
.vq-steps{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);gap:var(--vq-space-2);margin:0;padding:0;list-style:none}
.vq-steps li{display:flex;flex-direction:column;align-items:center;gap:var(--vq-space-1);padding-bottom:var(--vq-space-2);border-bottom:3px solid var(--vq-line);color:var(--vq-ink-subtle);font:var(--vq-weight-bold) var(--vq-text-sm)/1.1 var(--vq-font);text-align:center}
.vq-step-dot{display:inline-grid;place-items:center;width:1.75em;height:1.75em;border-radius:50%;background:var(--vq-surface-muted);color:var(--vq-ink-subtle);font:var(--vq-weight-bold) var(--vq-text-xs)/1 var(--vq-font)}
.vq-steps li.is-current{border-color:var(--vq-ink);color:var(--vq-ink)}
.vq-steps li.is-current .vq-step-dot{background:var(--vq-ink);color:var(--vq-on-ink)}
.vq-steps li.is-done{border-color:var(--vq-success);color:var(--vq-success)}
.vq-steps li.is-done .vq-step-dot{background:var(--vq-success);color:var(--vq-on-ink)}
.vq-steps[hidden]{display:none}
/* The app's own dialog (dialog.js; owner, 2026-10-10: never the browser's white confirm/prompt/alert): the dark card
   centred over a dimmed page, title, message, buttons on the right: Cancel quiet, the answer in ink (red to delete). */
.vq-dialog{box-sizing:border-box;width:min(calc(100vw - 2 * var(--vq-gutter)),28rem);max-width:none;max-height:calc(100dvh - 2 * var(--vq-gutter));margin:auto;padding:var(--vq-space-5);overflow-y:auto;border:var(--vq-border);border-radius:var(--vq-radius-lg);background:var(--vq-surface);color:var(--vq-ink);font-family:var(--vq-font);overflow-wrap:anywhere}
.vq-dialog[open]{display:grid;gap:var(--vq-space-3);animation:vq-dialog-in .18s ease-out}
.vq-dialog::backdrop{background:var(--vq-scrim)}
.vq-dialog-title{margin:0;font:var(--vq-weight-bold) var(--vq-text-lg)/1.25 var(--vq-font);letter-spacing:var(--vq-tracking-tight)}
.vq-dialog-message{margin:0;color:var(--vq-ink-muted);font:var(--vq-weight-medium) var(--vq-text-md)/1.45 var(--vq-font);white-space:pre-line}
.vq-dialog-message:empty{display:none}
.vq-dialog-field{display:grid;gap:var(--vq-space-2)}
.vq-dialog-field label{font:var(--vq-weight-bold) var(--vq-text-sm)/1.3 var(--vq-font)}
.vq-dialog-field input{box-sizing:border-box;width:100%;min-height:var(--vq-tap);padding:var(--vq-space-2) var(--vq-space-3);border:var(--vq-border);border-radius:var(--vq-radius-sm);background:var(--vq-paper);color:var(--vq-ink);font:var(--vq-weight-medium) var(--vq-text-md)/1.3 var(--vq-font)}
.vq-dialog-actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:var(--vq-space-3);margin-top:var(--vq-space-2)}
.vq-dialog .primary-action{height:auto;line-height:1.2;text-align:center;overflow-wrap:anywhere}
.vq-dialog .primary-action.is-danger{border-color:var(--vq-danger);background:var(--vq-danger);color:var(--vq-on-ink)}
.vq-dialog .primary-action:disabled{opacity:.45;cursor:not-allowed}
.vq-dialog .primary-action:disabled:hover{border-color:var(--vq-ink);background:var(--vq-ink)}
.vq-dialog .primary-action.is-danger:hover{border-color:var(--vq-danger);background:var(--vq-danger)}
.vq-dialog :focus-visible{outline:var(--vq-border-width) solid var(--vq-focus);outline-offset:var(--vq-border-width)}
@keyframes vq-dialog-in{from{opacity:0;transform:translateY(var(--vq-space-2))}to{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){.vq-dialog[open]{animation:none}}
