/* ============================================================
   ostentio-theme.css — the palette, in one place, in two moods.

   Every page used to carry its own copy of the same :root block. That was
   fine while there was one palette; with two it guarantees they drift. The
   tokens now live here and nowhere else, and a page that wants a colour asks
   for a token rather than writing a hex.

   HOW THE LIGHT THEME WORKS

   Most of it is the obvious inversion -- dark page, light page. The part that
   is not obvious is the overlays. A dark interface builds its depth by
   painting WHITE over the background at low opacity: borders, hovers, the
   raised edge on a button. Flip the background to near-white and every one of
   those becomes invisible. So they are tokens too (--lift-*), and in the light
   theme they are black instead. Anything that reads as "slightly lighter than
   its surroundings" on dark has to become "slightly darker" on light, and it
   cannot do that if the colour is written into the rule.

   The light palette is deliberately not white. #F7F7F5 is a shade off, the
   colour of a gallery wall rather than a spreadsheet, because the whole site
   is a frame around photographs of cards and a pure white ground makes the
   white borders of a slab disappear into it.
   ============================================================ */

:root{
  /* ---- surfaces ---- */
  --bg:#0E0E10;
  --panel:#161618;
  --panel-2:#1D1D20;
  --panel-3:#232327;        /* hover / pressed */
  --field-focus:#202024;    /* an input with the cursor in it */
  --line:#26262A;
  --line-strong:rgba(255,255,255,0.24);

  /* ---- type ---- */
  --text:#F2F2F4;
  --dim:#9C9CA3;
  --dim-2:#65656C;

  /* ---- accent: a filled button, and what sits on top of one ---- */
  --accent:#D9D9DE;
  --accent-hover:#FFFFFF;
  --on-accent:#0E0E10;

  /* ---- overlays ----
     Depth, as opacity over whatever is underneath. White on dark; black on
     light. Named by weight, not by colour, so a rule can say "a hairline" and
     stay correct in both themes. */
  --lift-1:rgba(255,255,255,0.05);
  --lift-2:rgba(255,255,255,0.08);
  --lift-3:rgba(255,255,255,0.14);
  --lift-4:rgba(255,255,255,0.24);
  --lift-5:rgba(255,255,255,0.32);
  --hairline:rgba(255,255,255,0.025);   /* the 44px scan lines */

  /* ---- depth ---- */
  --scrim:rgba(0,0,0,0.7);              /* behind a modal */
  --scrim-strong:rgba(0,0,0,0.9);
  /* The card viewer's backdrop specifically. It has to erase the page, not
     tint it: the viewer has no panel of its own -- the card, its title and its
     buttons sit straight on this -- so anything the backdrop lets through
     collides with them. On dark, near-black plus a blur does it. On light the
     equivalent is a near-opaque WHITE-out; the same dark scrim over a light
     page reads as a page that has been switched off rather than as a viewer. */
  --modal-scrim:rgba(8,8,10,0.92);
  --shadow-soft:rgba(0,0,0,0.35);
  --shadow-hard:rgba(0,0,0,0.6);
  --glass:rgba(6,6,7,0.72);             /* chips and tags over a photo */
  --glass-2:rgba(30,30,36,0.8);

  /* ---- the veil over a hero photograph ----
     A blurred card fills the top of a profile; these lay the page's own colour
     back over it so text can sit on top. Three weights because it is a
     gradient -- lightest where the photo should still read, heaviest where it
     has to hand over to the page below. In the light theme they are white,
     which is what turns the same blurred Charizard from a moody backdrop into
     a pale one. */
  --veil-1:rgba(14,14,16,0.42);
  --veil-2:rgba(14,14,16,0.62);
  --veil-3:rgba(14,14,16,0.95);
  --veil-fade:rgba(14,14,16,0.72);
  /* The blurred photo itself is pushed down on dark and lifted on light, so
     the veil has a similar amount of work to do either way. */
  --hero-photo:blur(7px) saturate(1.25) brightness(0.72);

  /* ---- the wash behind a hero ---- */
  --hero-tint-a:#2A3140;
  --hero-tint-b:#151A22;

  /* ---- the plinth a card photo sits on ---- */
  --card-face-a:#1B1B1F;
  --card-face-b:#101012;

  /* ---- status ---- */
  --positive:#5FD98A;
  --positive-soft:rgba(95,217,138,0.10);
  --positive-line:rgba(95,217,138,0.35);
  --negative:#F2726F;
  --negative-soft:rgba(242,114,111,0.08);
  --negative-line:rgba(242,114,111,0.40);


  /* ---- over a photograph ----
     The caption strip across the bottom of a featured card sits on the
     collector's own photo, under a dark gradient, not on the page. A photo is
     a photo in both themes, so this pair does not flip: theming it would put
     dark grey text on a dark scrim and lose it entirely. Everything else that
     LOOKS like it is over the photo -- the identity panel -- is really a
     frosted surface of its own and does follow the theme. */
  --on-photo:rgba(242,242,244,0.72);
  --photo-scrim:rgba(8,8,10,0.88);
  --hero-ring:rgba(217,217,222,0.5);
  --hero-glow:rgba(217,217,222,0.22);

  /* ---- the featured slab's shadow ----
     Two layers, not one. A single 90px blur reads as haze rather than as an
     object resting on something: what sells the weight is a tight contact
     shadow right under the edge, with the broad one behind it doing the
     ambient work. On dark this is nearly invisible either way -- a shadow
     cannot be darker than a near-black page -- so it is really the light
     theme that these numbers are for.

     --slab-glow is a GLOW, not a shadow: white on dark, to separate the card
     from the blurred photo behind it. On light it is switched off entirely
     rather than flipped to black, which would just be a third dark blur. */
  --slab-contact:rgba(0,0,0,0.75);
  --slab-mid:rgba(0,0,0,0.6);
  --slab-glow:rgba(255,255,255,0.14);

  /* ---- the plinth a card is displayed on, in a modal or on the homepage ---- */
  --face-a:#22222A;
  --face-b:#131316;

  /* The grade strip across the top of a card tile. Not a button, so it does
     not invert with the accent: on dark it is a bright label on a dark tile,
     and on light it stays a quiet grey one rather than becoming a black bar
     over every card in the grid. */
  --tag-bg:linear-gradient(120deg,#F2F2F4,#D9D9DE);
  --tag-ink:#0E0E10;
  --stage:#0B0B0D;             /* the cropper's working area */

  /* ---- geometry (identical in both themes) ---- */
  --r-tight:6px;
  --r-soft:18px;

  color-scheme:dark;
}

[data-theme="light"]{
  --bg:#F7F7F5;
  --panel:#FFFFFF;
  --panel-2:#F1F1EE;
  --panel-3:#E7E7E3;
  --field-focus:#FFFFFF;
  --line:#E3E3DE;
  --line-strong:rgba(0,0,0,0.20);

  --text:#15151A;
  --dim:#56565E;
  /* Not a mid-grey. These are 8-10px uppercase mono labels, and at that size
     anything lighter than this fails to read on paper-white. */
  --dim-2:#6E6E77;

  --accent:#15151A;
  --accent-hover:#000000;
  --on-accent:#FAFAF8;

  --lift-1:rgba(0,0,0,0.035);
  --lift-2:rgba(0,0,0,0.06);
  --lift-3:rgba(0,0,0,0.10);
  --lift-4:rgba(0,0,0,0.18);
  --lift-5:rgba(0,0,0,0.26);
  --hairline:rgba(0,0,0,0.028);

  /* Shadows on light have to be far softer. The same alpha that reads as
     depth against black reads as dirt against white. */
  --scrim:rgba(28,28,32,0.44);
  --scrim-strong:rgba(20,20,24,0.62);
  --modal-scrim:rgba(248,248,246,0.95);
  --shadow-soft:rgba(30,30,40,0.10);
  --shadow-hard:rgba(30,30,40,0.20);
  --glass:rgba(255,255,255,0.86);
  --glass-2:rgba(255,255,255,0.92);

  --veil-1:rgba(247,247,245,0.52);
  --veil-2:rgba(247,247,245,0.74);
  --veil-3:rgba(247,247,245,0.96);
  --veil-fade:rgba(247,247,245,0.84);
  --hero-photo:blur(7px) saturate(1.05) brightness(1.14);

  --hero-tint-a:#CBD5E8;
  --hero-tint-b:#E4E9F2;

  --card-face-a:#FFFFFF;
  --card-face-b:#EFEFEC;

  /* Both statuses darkened: the dark theme's green and coral are tuned to
     glow on black and turn to pastel mush on white. */
  /* #1E8F51 was the first pick and measured 3.84:1 on the page background --
     fine for the 5px dot, short of AA for the words beside it. */
  --positive:#177A44;
  --positive-soft:rgba(23,122,68,0.10);
  --positive-line:rgba(23,122,68,0.32);
  --negative:#C0392F;
  --negative-soft:rgba(192,57,47,0.08);
  --negative-line:rgba(192,57,47,0.34);


  --hero-ring:rgba(21,21,26,0.35);
  --hero-glow:rgba(21,21,26,0.10);

  --slab-contact:rgba(24,24,30,0.30);
  --slab-mid:rgba(24,24,30,0.20);
  --slab-glow:transparent;

  --face-a:#FFFFFF;
  --face-b:#ECECE8;

  --tag-bg:linear-gradient(120deg,#EEEEEA,#DFDFD9);
  --tag-ink:#15151A;
  --stage:#E9E9E5;

  color-scheme:light;
}

/* Switching should feel like a light coming on, not like a page reload --
   but only the flat colours animate. Transitioning shadows and gradients on
   every element at once is what makes a theme switch look like a stutter. */
@media (prefers-reduced-motion:no-preference){
  html.theme-animating,
  html.theme-animating body,
  html.theme-animating .panel,
  html.theme-animating [class*="card"],
  html.theme-animating [class*="btn"],
  html.theme-animating [class*="chip"]{
    transition:background-color .22s ease, color .22s ease, border-color .22s ease;
  }
}

/* ============================================================
   The wordmark is a link on every page.

   It was a <div> everywhere, which meant the one element every visitor
   instinctively clicks to get out of a dead end did nothing at all. Styled
   here rather than per page so the hover and focus behaviour cannot drift.
   ============================================================ */
a.brand-word{
  color:inherit; text-decoration:none; display:inline-block;
  transition:opacity .15s ease;
}
a.brand-word:hover{ opacity:0.72; }
a.brand-word:focus-visible{
  outline:2px solid var(--accent); outline-offset:4px; border-radius:4px;
}

/* ============================================================
   ACCOUNT MENU (built by ostentio-menu.js)
   The trigger has to read as a control, not as decoration. An avatar on its
   own is ambiguous -- half of people take it for a status indicator -- so it
   is a bordered pill with a caret, the caret turns over when the menu opens,
   and the whole thing changes state while open. */
.acct{ position:relative; }
.acct-btn{
  display:flex; align-items:center; gap:7px; cursor:pointer;
  /* 38px and an 11px radius are not arbitrary: they are .tbtn's, the icon
     buttons this sits beside in the topbar. At 34px and a pill radius it read
     as a different kind of thing that had landed in the row by accident, and
     with align-items:center the two heights left it sitting 2px low. */
  height:38px; padding:0 10px 0 6px; border-radius:11px;
  /* Glass, again like .tbtn: on a profile this row floats over the collector's
     hero photo, and a faint white overlay vanishes against a bright card. */
  background:var(--glass-2); border:1px solid var(--lift-3);
  backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px);
  color:var(--text);
  transition:background .15s ease, border-color .15s ease;
}
.acct-btn:hover{ border-color:var(--lift-4); }
.acct-btn[aria-expanded="true"]{ border-color:var(--lift-5); }
.acct-btn:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
.acct-av{
  width:24px; height:24px; border-radius:50%; flex:none; overflow:hidden;
  background:linear-gradient(150deg, var(--accent), var(--dim));
  color:var(--on-accent); display:flex; align-items:center; justify-content:center;
  font-family:'Bricolage Grotesque', sans-serif; font-size:10px; font-weight:700;
  letter-spacing:0.02em; text-transform:uppercase;
}
.acct-av img{ width:100%; height:100%; object-fit:cover; }
.acct-caret{
  width:13px; height:13px; color:var(--text); opacity:0.72; flex:none;
  transition:transform .18s ease, opacity .15s ease;
}
.acct-btn:hover .acct-caret{ opacity:1; }
.acct-btn[aria-expanded="true"] .acct-caret{ transform:rotate(180deg); opacity:1; }

.acct-menu{
  position:absolute; top:calc(100% + 9px); right:0; z-index:90; width:226px;
  background:var(--panel); border:1px solid var(--line); border-radius:14px;
  box-shadow:0 3px 6px -2px var(--slab-contact), 0 26px 48px -18px var(--slab-mid);
  padding:6px; text-align:left;
  animation:acctIn .14s ease;
}
@keyframes acctIn{ from{ opacity:0; transform:translateY(-4px); } }
@media (prefers-reduced-motion:reduce){ .acct-menu{ animation:none; } }
.acct-head{
  padding:11px 12px 10px; margin:-6px -6px 6px;
  border-bottom:1px solid var(--line);
}
.acct-head .n{
  font-family:'Bricolage Grotesque', sans-serif; font-size:13.5px; font-weight:600;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.acct-head .h{
  font-family:'Martian Mono', monospace; font-size:9.5px; color:var(--dim-2); margin-top:3px;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.acct-item{
  display:flex; align-items:center; gap:10px; width:100%;
  padding:9px 10px; border-radius:9px; cursor:pointer;
  font-family:'Bricolage Grotesque', sans-serif; font-size:13px;
  color:var(--text); background:none; border:none; text-align:left;
}
.acct-item svg{ width:16px; height:16px; color:var(--dim); flex:none; }
.acct-item:hover, .acct-item:focus-visible{ background:var(--panel-3); outline:none; }
.acct-item:focus-visible{ box-shadow:inset 0 0 0 1px var(--lift-4); }
.acct-item.danger{ color:var(--negative); }
.acct-item.danger svg{ color:var(--negative); }
.acct-sep{ height:1px; background:var(--line); margin:6px -6px; }

@media (max-width:520px){
  .acct-menu{ width:min(258px, calc(100vw - 36px)); }
}


/* Pages whose topbar is brand-on-the-left and one link on the right need a
   group so the menu can sit beside that link rather than replace it. */
.topbar-right{ display:flex; align-items:center; gap:12px; }

/* ------------------------------------------------------------------
   The menu drops out of the topbar and over the page, so the topbar has to
   win against the page content. Most pages gave BOTH .topbar and .wrap
   z-index:2 and let source order settle it -- which put the page on top, and
   a child cannot paint above something its own ancestor sits behind. The menu
   opened correctly and rendered underneath the first heading.

   Two selectors deep so this beats the per-page rule regardless of the order
   the stylesheets happen to load in.
   ------------------------------------------------------------------ */
body .topbar{ position:relative; z-index:40; }
