/* app/web.css — the app host's shell and its sign-in screens
   (docs/design/standalone-app.md, "Design — an iOS app that happens to run
   in a browser"). Loaded only by app/web.html and identity.py's server-
   rendered sign-in pages, after app.css, whose tokens it uses; every rule is
   scoped under `html.web`, so the Telegram Mini App (index.html, which never
   loads this file) is untouched. */

/* ── the shell: 100dvh, the page itself never scrolls ─────────────────────
   A fixed header, a scrolling content area and the bottom tab bar; the
   document is overflow: hidden so there is no rubber-band of the whole page
   and no browser pull-to-refresh, and only the content area scrolls. */
html.web, html.web body { height: 100%; overflow: hidden; overscroll-behavior: none; }
html.web .app { height: 100vh; height: 100dvh; min-height: 0; }
html.web .top { flex-shrink: 0; padding-left: calc(22px + env(safe-area-inset-left, 0px)); padding-right: calc(22px + env(safe-area-inset-right, 0px)); }
/* .content (the large title and the screens) is the one scroller; each
   tab's own scroll position is kept by app.js across tab switches. */
html.web .content { min-height: 0; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
html.web .screen, html.web .large {
  padding-left: calc(22px + env(safe-area-inset-left, 0px));
  padding-right: calc(22px + env(safe-area-inset-right, 0px));
}
html.web .composer { padding-left: calc(12px + env(safe-area-inset-left, 0px)); padding-right: calc(12px + env(safe-area-inset-right, 0px)); }
html.web .tabs { padding-left: calc(10px + env(safe-area-inset-left, 0px)); padding-right: calc(10px + env(safe-area-inset-right, 0px)); }
html.web .gate { min-height: 100vh; min-height: 100dvh; }

/* Controls behave like controls: app.css's own rule, shared with the Mini
   App; the sign-in button's pressed state is this page's. */
html.web .signin-btn:active { opacity: .7; }

/* Signed out (app/login.js): only the sign-in screen shows, whatever app.js
   last drew behind it. */
html.web.signed-out #app, html.web.signed-out #gate { display: none !important; }

/* ── sign-in, code and verify ─────────────────────────────────────────────
   A page, not a card: top-anchored, no border or shadow round the whole
   thing, one column that centres itself. app/login.js's #signin and
   identity.py's server-rendered pages (_page()) share this exact markup —
   the mark, wordmark, tagline/title, the two forms and the footer. */
html.web .signin {
  min-height: 100vh; min-height: 100dvh; display: flex; justify-content: center;
  padding-top: calc(64px + env(safe-area-inset-top, 0px));
  padding-left: calc(22px + env(safe-area-inset-left, 0px));
  padding-right: calc(22px + env(safe-area-inset-right, 0px));
  padding-bottom: calc(22px + env(safe-area-inset-bottom, 0px));
  overflow-y: auto; height: 100%;
}
html.web .signin-frame {
  width: 100%; max-width: 380px; display: flex; flex-direction: column;
  align-items: center; gap: 14px; text-align: center;
}
html.web .signin-mark { width: 72px; height: 72px; border-radius: 22px; }
html.web .signin-wordmark { font-family: var(--serif); font-size: 40px; font-weight: 600; color: var(--accent); }
html.web .signin-tagline { font-family: var(--serif); font-weight: 500; font-size: 26px; line-height: 1.15; letter-spacing: -.01em; margin: 0; }
html.web .signin-text { margin: 0; color: var(--ink2); font-size: 16px; line-height: 1.5; }
html.web .signin-form { width: 100%; display: flex; flex-direction: column; gap: 10px; margin: 8px 0 0; text-align: left; }
/* Kept for a screen reader, off screen for everyone else — the input's own
   placeholder carries the visible label (AC5). */
html.web .signin-label {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
html.web .signin-input {
  height: 52px; padding: 0 16px; border: 1.5px solid var(--line); border-radius: var(--radius);
  background: var(--card); color: var(--ink); font: 400 17px var(--sans); outline: none;
  -webkit-appearance: none; appearance: none;
}
html.web .signin-input:focus { border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); }
html.web .signin-input.code { font-variant-numeric: tabular-nums; letter-spacing: .4em; font-size: 22px; text-align: center; }
html.web .signin-btn {
  display: flex; align-items: center; justify-content: center; height: 52px; border-radius: 999px;
  background: var(--accent); color: var(--accent-ink); font: 600 16px/1 var(--sans); text-decoration: none;
  border: 0; cursor: pointer;
}
html.web .signin-link { color: var(--accent); font-weight: 600; padding: 8px 0; }
/* "Or try the demo first" and the demo page's waitlist link: links, drawn
   as the sign-in's own text buttons. */
html.web .signin-try { text-align: center; text-decoration: none; }
html.web .signin-error { width: 100%; margin: 0; color: var(--warn); background: var(--warn-soft); border-radius: var(--radius); padding: 10px 14px; font-size: 15px; text-align: left; }
html.web .signin-footer { margin: 18px 0 0; color: var(--muted); font-size: 13px; }

html.web .passkey-offer {
  position: fixed; left: 12px; right: 12px; bottom: calc(env(safe-area-inset-bottom) + 84px); z-index: 30;
  max-width: 420px; margin: 0 auto; background: var(--card); border: 1px solid var(--line);
  border-radius: 22px; padding: 20px 20px 14px; display: flex; flex-direction: column; gap: 10px;
  box-shadow: var(--shadow-signin);
}
html.web .passkey-offer[hidden] { display: none; }
html.web .passkey-offer-title { font-family: var(--serif); font-weight: 500; font-size: 22px; }
html.web .passkey-offer-text { margin: 0; color: var(--ink2); font-size: 15px; line-height: 1.45; }

@media (prefers-reduced-motion: reduce) {
  html.web *, html.web *::before, html.web *::after { transition: none !important; animation: none !important; }
}
@media (prefers-reduced-motion: no-preference) {
  html.web .signin-btn { transition: opacity .15s ease-out; }
}
/* The setup page (provision.py): the two documents and the one checkbox. */
html.web .setup-doc { border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 14px; }
html.web .setup-doc summary { font-weight: 600; cursor: pointer; }
html.web .setup-doc-text { white-space: pre-wrap; max-height: 40vh; overflow: auto; margin-top: 8px; font-size: 14px; line-height: 1.5; color: var(--ink2); }
html.web .setup-check { display: flex; gap: 10px; align-items: flex-start; font-size: 15px; line-height: 1.45; color: var(--ink2); }
html.web .setup-check input { margin-top: 3px; flex: none; }

/* ── the install card (app/push.js) ─────────────────────────────────────
   One card between the header and the screen: on iOS "Add Doddle to your
   Home Screen", elsewhere (or once installed) "Turn on notifications" and,
   where Chrome offers it, "Install Doddle". Dismissed per member on the
   server. */
html.web .install-card {
  flex-shrink: 0; position: relative; display: flex; flex-direction: column; gap: 10px;
  margin: 0 calc(22px + env(safe-area-inset-right, 0px)) 10px calc(22px + env(safe-area-inset-left, 0px));
  padding: 14px 44px 14px 16px; background: var(--accent-soft); border-radius: var(--radius);
}
html.web .install-card[hidden] { display: none; }
html.web .install-text { display: flex; flex-direction: column; gap: 2px; }
html.web .install-text .main { font-weight: 600; }
html.web .install-text .sub { font-size: 13px; color: var(--ink2); }
html.web .install-actions { display: flex; flex-wrap: wrap; gap: 8px; }
html.web .install-btn {
  border: 0; border-radius: 999px; padding: 9px 16px; font: inherit; font-weight: 600;
  background: var(--accent); color: var(--accent-ink);
}
html.web .install-btn.soft { background: var(--card); color: var(--accent); }
html.web .install-btn:active { opacity: .7; }
html.web .install-close {
  position: absolute; top: 8px; right: 8px; width: 32px; height: 32px; border: 0; border-radius: 50%;
  background: transparent; color: var(--muted); font-size: 15px;
}

/* The card's "Show me how" button opens the shell's own #sheet
   (app/push.js's showHowToInstall) with these three steps. */
html.web .install-steps { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 10px; font-size: 15px; line-height: 1.45; color: var(--ink2); }
html.web .install-steps li { padding-left: 4px; }
html.web .install-note { margin: 14px 0 0; font-size: 15px; line-height: 1.45; color: var(--ink2); }
/* The install page (app_get.py, /get): a store link not configured yet is a
   dimmed button that goes nowhere; the QR code sits on white for the camera. */
html.web .get-soon { opacity: .45; cursor: default; }
html.web .get-note { font-size: 14px; }
html.web .get-qr { margin: 8px auto 0; border-radius: 12px; max-width: 100%; height: auto; }
html.web .get-frame .signin-btn { width: 100%; padding: 0 18px; }
html.web .get-url { margin-bottom: 14px; word-break: break-all; user-select: all; -webkit-user-select: all; font-size: 14px; }
html.web .get-inapp { font-weight: 600; font-size: 18px; margin-bottom: 14px; }
html.web .get-waitlist { display: block; margin-top: 16px; text-align: center; }
html.web [hidden] { display: none !important; }
html.web a.btn, a.btn { text-decoration: none; }

html.web .get-chrome, html.web .get-safari { margin-bottom: 12px; }
