/* Winloom design tokens — brand foundation §10. "Brass on ink: the instrument,
   not the dashboard." Brass appears on ONE element per view. Never two. */
@import url('https://fonts.googleapis.com/css2?family=Newsreader:ital,opsz,wght@0,6..72,400;0,6..72,500;1,6..72,400&family=Archivo:wght@400;500;600&family=DM+Mono:wght@400;500&display=swap');

:root {
  --ink:        #121A16;   /* Loom Ink — green-biased near-black */
  --brass:      #B98A34;   /* the weft. Single accent */
  --loomstone:  #EFF1EC;   /* light ground, cool neutral */
  --verdigris:  #35786A;   /* semantic positive */
  --signal:     #AF4835;   /* risk and loss ONLY. never decorative */
  --slate:      #5C6862;   /* secondary text */

  --ground: var(--loomstone);
  --figure: var(--ink);
  --accent: var(--brass);

  --display: 'Newsreader', Georgia, serif;
  --ui:      'Archivo', system-ui, sans-serif;   /* deliberately NOT Inter */
  --mono:    'DM Mono', ui-monospace, monospace;
}
@media (prefers-color-scheme: dark) {
  :root { --ground: var(--ink); --figure: var(--loomstone); --accent: #C99B45; }
}
[data-theme="dark"] { --ground: var(--ink); --figure: var(--loomstone); --accent: #C99B45; }

* { box-sizing: border-box; }
body {
  margin: 0; background: var(--ground); color: var(--figure);
  font: 400 16px/1.55 var(--ui); -webkit-font-smoothing: antialiased;
  position: relative;   /* anchors the warp layer below to the PAGE, not the viewport */
}

/* Warp hairline — the vertical texture from brand foundation §10.
   It used to be a background-image on <body>, which repeated at full strength
   from the first pixel to the last. At 26px spacing down a whole page that stops
   reading as texture and starts reading as a grid ruled over the content.
   It is now a masked layer: present at the top, gone by ~520px, so the page
   emerges from the texture rather than being laid across it.
   ABSOLUTE and not FIXED on purpose — fixed would pin the fade to the viewport,
   so the texture would follow the reader down the page, which is precisely the
   opposite of fading out. */
body::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 520px;
  pointer-events: none;   /* decoration must never eat a click */
  z-index: 0;
  background-image: repeating-linear-gradient(90deg,
    color-mix(in srgb, var(--figure) 4%, transparent) 0 1px, transparent 1px 26px);
  -webkit-mask-image: linear-gradient(to bottom,
    rgba(0,0,0,1) 0, rgba(0,0,0,.6) 45%, rgba(0,0,0,0) 100%);
  mask-image: linear-gradient(to bottom,
    rgba(0,0,0,1) 0, rgba(0,0,0,.6) 45%, rgba(0,0,0,0) 100%);
}

/* Content sits above the warp layer. Without this the texture paints over the
   page rather than under it — and on a browser without mask-image support, over
   it at full strength for 520px. */
body > * { position: relative; z-index: 1; }
h1, h2, h3 { font-family: var(--display); font-weight: 400; letter-spacing: -0.01em; margin: 0 0 .5em; }
h1 { font-size: clamp(2rem, 4.5vw, 3.25rem); line-height: 1.08; }
h2 { font-size: 1.5rem; }
.eyebrow {
  font: 500 .72rem/1 var(--mono); letter-spacing: .14em; text-transform: uppercase;
  color: var(--slate);
}
.mono, td.num { font-family: var(--mono); font-variant-numeric: tabular-nums; }
a { color: var(--figure); text-decoration-color: color-mix(in srgb, var(--figure) 35%, transparent); }
.muted { color: var(--slate); }

.wrap { max-width: 68rem; margin: 0 auto; padding: 2rem 1.5rem 4rem; }
.card {
  background: color-mix(in srgb, var(--ground) 92%, var(--figure));
  border: 1px solid color-mix(in srgb, var(--figure) 12%, transparent);
  border-radius: 10px; padding: 1.5rem;
}

/* Brass is the accent and it is used ONCE per view — here, the primary action. */
.btn {
  display: inline-block; font: 500 .95rem/1 var(--ui); padding: .85rem 1.4rem;
  border: 1px solid var(--accent); border-radius: 8px; cursor: pointer;
  background: var(--accent); color: var(--ink); text-decoration: none;
}
.btn:hover { filter: brightness(1.07); }
.btn-quiet {
  background: transparent; color: var(--figure);
  border-color: color-mix(in srgb, var(--figure) 25%, transparent);
}
label { display: block; font: 500 .8rem/1 var(--ui); margin: 0 0 .4rem; color: var(--slate); }
input[type=email], input[type=password], input[type=text] {
  width: 100%; padding: .8rem .9rem; font: 400 1rem var(--ui);
  color: var(--figure); background: color-mix(in srgb, var(--ground) 88%, var(--figure));
  border: 1px solid color-mix(in srgb, var(--figure) 18%, transparent); border-radius: 8px;
}
input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.field { margin-bottom: 1.1rem; }
.err {
  border-left: 3px solid var(--signal); padding: .7rem .9rem; margin-bottom: 1.2rem;
  background: color-mix(in srgb, var(--signal) 9%, transparent); font-size: .92rem;
}

/* Login: single centred column on ink. */
.auth { min-height: 100vh; display: grid; place-items: center; padding: 2rem; }
.auth .panel { width: 100%; max-width: 25rem; }
.brandrow { display: flex; align-items: center; gap: .8rem; margin-bottom: 2.5rem; }
.brandrow img { width: 46px; height: auto; }
.brandrow .word { font: 400 1.9rem/1 var(--display); letter-spacing: -.015em; }

/* App shell */
header.top {
  display: flex; align-items: center; gap: 1.25rem; padding: .9rem 1.5rem;
  border-bottom: 1px solid color-mix(in srgb, var(--figure) 12%, transparent);
}
header.top img { width: 30px; }
header.top .word { font: 400 1.25rem/1 var(--display); }
header.top nav { margin-left: auto; display: flex; gap: 1.25rem; font-size: .92rem; }
.grid { display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
table { width: 100%; border-collapse: collapse; font-size: .92rem; }
th {
  text-align: left; font: 500 .7rem/1 var(--mono); letter-spacing: .12em;
  text-transform: uppercase; color: var(--slate); padding: .6rem .5rem;
  border-bottom: 1px solid color-mix(in srgb, var(--figure) 14%, transparent);
}
td { padding: .65rem .5rem; border-bottom: 1px solid color-mix(in srgb, var(--figure) 8%, transparent); }
.pill {
  font: 500 .7rem/1 var(--mono); padding: .3rem .55rem; border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--figure) 20%, transparent); color: var(--slate);
}
.pill.ok { color: var(--verdigris); border-color: color-mix(in srgb, var(--verdigris) 45%, transparent); }

/* winloom-06 — dashboard action surface */
.stats{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,220px));
       gap:1rem;margin:2rem 0}
.stats .card p{margin:0}
.stats .stat{font-size:2.1rem;line-height:1.1;margin:.15rem 0}
.stats .muted{font-size:.82rem}
.addbox{border:1px solid var(--hairline,rgba(255,255,255,.10));border-radius:12px;
        padding:1.5rem 1.5rem 1.75rem;margin:2.5rem 0}
.addbox h2{margin:0 0 .25rem}
.addbox .muted{margin:0 0 1.25rem;font-size:.9rem}
.addform{display:flex;gap:1rem;align-items:flex-end;flex-wrap:wrap}
.addform .field{flex:1 1 220px;margin:0}
.addform .btn{flex:0 0 auto}
.flash{border-left:2px solid var(--verdigris,#35786A);padding:.65rem 1rem;
       margin:1.5rem 0;font-size:.92rem}
.errs{list-style:none;padding:0;margin:1rem 0 0;font-size:.88rem;
      color:var(--signal,#AF4835)}

/* winloom-07 — an <input> with no type attribute is still a text input.
   input[type=text] does not match it; :not() on the types that style
   themselves differently does. */
input:not([type=hidden]):not([type=checkbox]):not([type=radio]):not([type=submit]):not([type=button]) {
  background: color-mix(in srgb, var(--ground) 88%, var(--figure) 12%);
  color: var(--figure);
  border: 1px solid color-mix(in srgb, var(--ground) 70%, var(--figure) 30%);
}
input::placeholder { color: color-mix(in srgb, var(--ground) 45%, var(--figure) 55%); }

/* winloom-09 — the account page. Citations are part of the type hierarchy,
   not a footnote: a claim and its provenance are one block. */
.jobline{display:flex;gap:.75rem;align-items:center;margin:1.25rem 0 0;flex-wrap:wrap}
.jobline .err{color:var(--signal,#AF4835);font-size:.8rem}
.claims{margin:1.5rem 0 0}
.claim{padding:1.1rem 0;border-top:1px solid color-mix(in srgb,var(--ground) 88%,var(--figure) 12%)}
.claim dt{font-size:.78rem;letter-spacing:.04em;opacity:.65;margin:0 0 .35rem}
.claim dd{margin:0;font-size:1.02rem}
.claim .vals{margin:0;padding-left:1.1rem}
.cite{font-size:.72rem;opacity:.6;margin:.5rem 0 0}
.cite a{color:inherit}

/* winloom-14 — profile, avatars, admin user editor.
   Appended rather than rewritten: the file already carries the brand tokens and
   the warp layer, and replacing it wholesale to add ten rules is how a fade
   nobody asked to change gets reverted by accident. */

/* Panels are scoped to .wrap on purpose. The auth pages (/sign-in,
   /set-password) also use .panel, but they sit in .auth, not .wrap — an
   unscoped rule here would put a card border around the login box, which is a
   design change to a page nobody asked me to touch. */
.wrap .panel {
  border: 1px solid color-mix(in srgb, var(--figure) 12%, transparent);
  border-radius: 12px;
  padding: 1.5rem 1.5rem 1.75rem;
  margin: 1.75rem 0;
}
.panel-h  { margin: 0 0 .25rem; font-size: 1.2rem; }
.panel-sub{ margin: 0 0 1.25rem; font-size: .9rem; max-width: 46rem; }
.panel-sub:last-child { margin-bottom: 0; }

/* Forms that are a column of fields, not a layout. Full-width inputs on a
   68rem page put the label a screen away from the value. */
.narrow { max-width: 26rem; }
.rowbtns { display: flex; gap: .75rem; align-items: center; flex-wrap: wrap; }
.rowbtns input[type=file] { flex: 1 1 14rem; font-size: .88rem; }

.btn-sm { padding: .5rem .9rem; font-size: .85rem; }

/* Avatar. One rule for both the image and the initials fallback so the two
   cannot drift apart — the fallback is what every user sees on day one. */
.avatar {
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px; object-fit: cover; flex: 0 0 auto;
  background: color-mix(in srgb, var(--ground) 82%, var(--figure));
  border: 1px solid color-mix(in srgb, var(--figure) 14%, transparent);
}
.avatar-initials {
  font: 500 1rem/1 var(--ui); letter-spacing: .02em;
  color: var(--slate); user-select: none;
}

.profile-head { display: flex; align-items: center; gap: 1.25rem; margin: .5rem 0 2rem; }
.avatar-form  { display: flex; align-items: flex-start; gap: 1.25rem; flex-wrap: wrap; }
.avatar-form-controls { flex: 1 1 18rem; min-width: 0; }

/* The nav entry is the avatar itself. It doubles as the "am I signed in as the
   right person" indicator, which is the question a shared laptop raises. */
header.top nav .navme {
  display: inline-flex; align-items: center; gap: .5rem; text-decoration: none;
}
header.top nav .navme .avatar { width: 26px; height: 26px; font-size: 10px; }

/* Tables of passkeys wrap badly on a phone; let them scroll rather than
   squeeze the action column to nothing. */
@media (max-width: 640px) {
  .wrap .panel { padding: 1.25rem 1rem 1.5rem; }
  .profile-head { gap: 1rem; }
}
