/* Base reset + the mandatory globals from the eski-style skill (§3).
   Component styles live with their components; this is only the ground layer. */

*{box-sizing:border-box}
html,body{margin:0;height:100%}

body{
  background:var(--paper);
  color:var(--ink);
  font-family:var(--font);
  font-size:var(--fs);
  line-height:1.5;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}

/* The app fills the viewport (1440 is a prototyping canvas only, CANON §G). */
#stage{height:100%}

/* Mandatory button reset: without it an unstyled button falls back to browser
   black and vanishes on dark surfaces (eski-style §3). `padding:0` is part of the
   reset — the UA default is an asymmetric `1px 6px`, which on a fixed-size,
   grid-centred icon button (.iconbtn/.cgadd/.more2/…) shrinks the content box and
   pushes the glyph ~2px off-centre, so its hover box no longer aligns to the icon.
   Buttons that want padding (.btn, .menu button, .cbar .fbtn, …) set their own. */
button{background:none;border:0;padding:0;color:inherit;font:inherit;cursor:pointer}

a{color:inherit;text-decoration:none}

/* Images never blow out their container. A user-uploaded photo can be any size;
   without this, one dropped into a spot that lacks explicit sizing renders at its
   natural pixels and breaks the layout (owner bug 2026-08-28 — an uploaded avatar
   overflowed the edit dialog). Components that need a specific fit (.av, .railimg,
   media wells) still set their own width/height/object-fit on top of this floor. */
img{max-width:100%;height:auto}

/* Drag-and-drop upload hint — any surface wired with enableDropUpload() gets this overlay
   while files are dragged over it. pointer-events:none so the drop still lands on the target. */
.dropping{position:relative}
.dropping::after{content:"Drop files to upload";position:absolute;inset:8px;z-index:60;display:grid;place-items:center;
  border:2px dashed var(--line2);border-radius:var(--r);background:color-mix(in srgb, var(--paper), transparent 12%);
  color:var(--soft);font-size:var(--fs-sm);font-weight:600;pointer-events:none}

/* the eski! wordmark — one class everywhere it appears (sign-in, loading, feed,
   profile). Uses the Gnomon wordmark face (falls back to the body face until the
   Gnomon subset is embedded). Always the text "eski!" to match the "e!" logo.
   `.wm` (the header/card sized variant) and `.brand` (the shared-view header) render
   the same wordmark, so they get the Gnomon face here too — the Feed's `.wm` used only
   its size rule and was rendering in the body font (owner: "the main wordmark isn't gnomon"). */
.wordmark,.wm,.brand{font-family:var(--font-wordmark)}
.wordmark{font-weight:700;letter-spacing:-.01em}

/* Loading: spell out "eski!" one character at a time on a ~2s loop. Each letter fades/rises
   in on a small stagger (--i), holds, then clears so the cycle repeats smoothly and cleanly. */
.loadword{display:inline-flex;font-size:var(--fs-xl);color:var(--muted)}
.loadword .lc{opacity:0;animation:eski-type 2s cubic-bezier(.4,0,.2,1) infinite;animation-delay:calc(var(--i) * .13s)}
@keyframes eski-type{
  0%   {opacity:0;transform:translateY(3px)}
  9%   {opacity:1;transform:translateY(0)}
  68%  {opacity:1;transform:translateY(0)}
  82%  {opacity:0;transform:translateY(-2px)}
  100% {opacity:0;transform:translateY(-2px)}
}
@media (prefers-reduced-motion:reduce){.loadword .lc{animation:none;opacity:1}}

/* No visible scrollbars, but keep the scroll (eski-style §3). */
*{scrollbar-width:none}
*::-webkit-scrollbar{width:0;height:0;display:none}

/* Icon helper output: stroke inherits currentColor so an icon takes its
   parent's colour. */
.ic{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2;
    stroke-linecap:round;stroke-linejoin:round;flex:none}
.ic.sm{width:14px;height:14px}

/* Placeholder for a route whose real screen isn't ported yet. `.screen` layout
   is owned by styles/shell.css (the flex shell pane) — defining it here too would
   be the duplicate-selector bug this repo guards against — so the placeholder
   centres its own `.ph` with margin:auto inside that flex pane instead. */
.screen .ph{margin:auto;text-align:center;color:var(--muted);font-size:var(--fs-xl);font-weight:600}
.screen .ph small{display:block;color:var(--muted);font-size:var(--fs-sm);
    font-weight:400;margin-top:var(--s2)}
