/* THE LOADING SCREEN's one stylesheet (src/shared/ui/LoadingScreen.tsx; Ward, 2026-10-02).
 *
 * Linked from index.html, not imported by the bundle: index.html carries the same markup inside #root so the
 * first paint is never blank, and that copy is styled before any JS (or tokens.css, which the bundle brings)
 * exists. External on purpose: the CSP is 'self' with no nonce, so nothing inline (see theme-boot.js). React's
 * LoadingScreen uses these same classes, so the pre-JS copy and the React one cannot drift.
 *
 * COLOURS: the design-system tokens when they are loaded (var(--…)), else the same values from
 * design-system/tokens.json, light then dark (paper-1 page, ink-900 text, ink-500 muted, matcha-600 accent).
 * The theme is <html data-theme>, set pre-paint by theme-boot.js; with no attribute at all (the script
 * refused), the OS setting decides.
 * MOTION (design-system/README.md, Visual foundations): quiet, --ease-out / --ease-inout curves, no bounce,
 * nothing at all under prefers-reduced-motion. */

html { background: #f6f4eb; }
html[data-theme="dark"] { background: #1a1f17; }
@media (prefers-color-scheme: dark) { html:not([data-theme]) { background: #1a1f17; } }

.loading-screen {
  --ls-ink: var(--text-body, #20261d);
  --ls-muted: var(--text-muted, #5e6858);
  --ls-accent: var(--accent, #4c7a34);
  --ls-ease: cubic-bezier(.65,0,.35,1);
  --ls-delay: 250ms; /* React sets it inline (LoadingScreen.tsx: the pre-JS copy's clock, carried over) */
  display: grid; place-items: center; align-content: center; gap: 20px;
  box-sizing: border-box; width: 100%; padding: 32px 16px;
  text-align: center; color: var(--ls-ink);
  opacity: 0;
  animation: ls-appear 420ms cubic-bezier(.22,1,.36,1) var(--ls-delay, 250ms) both;
}
[data-theme="dark"] .loading-screen { --ls-ink: var(--text-body, #edebe0); --ls-muted: var(--text-muted, #99a18d); --ls-accent: var(--accent, #85ae60); }
@media (prefers-color-scheme: dark) {
  html:not([data-theme]) .loading-screen { --ls-ink: #edebe0; --ls-muted: #99a18d; --ls-accent: #85ae60; }
}

/* fill: the whole viewport (100vh first, for a browser without dvh). area: the page's main area under the
   shell's sticky header (--shell-header-h, styles.css) less the main's own padding. */
.loading-screen--fill { min-height: 100vh; min-height: 100dvh; }
.loading-screen--area {
  min-height: calc(100vh - var(--shell-header-h, 65px) - 160px);
  min-height: calc(100dvh - var(--shell-header-h, 65px) - 160px);
}

/* The mark, still (issue 854): the ensō in ink-900, its five dots in kaki-600, each flipping in dark (the tokens when
   loaded, else tokens.json's values, light then dark). No sheen, no Signature: nothing on the loading screen draws. */
.loading-screen { --ls-mark-ink: var(--ink-900, #20261d); --ls-mark-dot: var(--kaki-600, #b44c1b); }
[data-theme="dark"] .loading-screen { --ls-mark-ink: var(--ink-900, #edebe0); --ls-mark-dot: var(--kaki-600, #ea9055); }
@media (prefers-color-scheme: dark) {
  html:not([data-theme]) .loading-screen { --ls-mark-ink: #edebe0; --ls-mark-dot: #ea9055; }
}
.loading-mark { display: block; line-height: 0; }
.loading-mark-svg { display: block; block-size: 64px; inline-size: auto; aspect-ratio: 152 / 143; }
.loading-mark-ink { fill: var(--ls-mark-ink); }
.loading-mark-dot { fill: var(--ls-mark-dot); }
@media (max-width: 480px) {
  .loading-mark-svg { block-size: 52px; }
}

/* Three accent dots breathing in a stagger (also the auth interstitial's, features/auth-transition). */
.loading-dots { display: inline-flex; align-items: center; gap: 10px; height: 12px; }
.loading-dots > i {
  display: block; width: 8px; height: 8px; border-radius: 50%; background: var(--ls-accent, var(--accent, #4c7a34));
  opacity: 0.35; transform: scale(0.75);
  animation: ls-breathe 1.4s var(--ls-ease) infinite;
  animation-delay: var(--ls-delay, 0ms);
}
.loading-dots > i:nth-child(2) { animation-delay: calc(var(--ls-delay, 0ms) + 0.18s); }
.loading-dots > i:nth-child(3) { animation-delay: calc(var(--ls-delay, 0ms) + 0.36s); }
.loading-dots[data-still] > i { animation: none; opacity: 0.5; transform: none; }

.loading-caption {
  margin: 0; color: var(--ls-muted);
  font-family: "Schibsted Grotesk", "Zen Kaku Gothic New", system-ui, sans-serif;
  font-size: 13px; letter-spacing: 0.08em; text-transform: uppercase;
}
.loading-caption:lang(ja) { letter-spacing: 0.04em; }

@keyframes ls-appear { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes ls-ink { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } }
@keyframes ls-breathe {
  0%, 100% { opacity: 0.35; transform: scale(0.75); }
  40% { opacity: 1; transform: scale(1.15); }
}

/* Reduced motion: no fade, no breathing. Still appears after the delay (a step, not a fade), so a
   fast load still never flashes it: a static mark, three still dots, the caption. */
@media (prefers-reduced-motion: reduce) {
  .loading-screen { animation: ls-appear-still 1ms step-end var(--ls-delay, 250ms) both; transform: none; }
  .loading-dots > i, .loading-dots > i:nth-child(2), .loading-dots > i:nth-child(3) { animation: none; opacity: 0.6; transform: none; }
}
@keyframes ls-appear-still { from { opacity: 0; } to { opacity: 1; } }

/* InlineLoading (shared/ui LoadingScreen.tsx): a wait inside a loaded page, the same dots, small, in line */
.loading-inline { display: inline-flex; align-items: center; gap: 10px; padding: 8px 0; color: var(--text-muted, #6b6b5f); }
.loading-inline .loading-dots { height: 8px; gap: 6px; opacity: 1; animation: none; }
.loading-inline .loading-dots > i { width: 6px; height: 6px; }
.loading-inline-caption { font-size: 13.5px; }
