/* ------------------------------------------------------------------ *
 * Tokens
 * ------------------------------------------------------------------ */

/*
 * The site is dark, always - not a dark *mode*.
 *
 * It used to follow the visitor's system setting, which meant half of them met
 * a pale beige site and the other half met this one. An identity cannot be a
 * coin toss, and near-black is the whole reason the work looks like it is lit
 * in a gallery. If a light variant is ever wanted back, it is one block of
 * these same tokens under `@media (prefers-color-scheme: light)`.
 *
 * Palette: The Nail Coven. Sampled from the studio's own logo rather than
 * invented - the values below come out of that file, which is 79% pure black
 * with a violet rim-light and pale lilac lettering.
 *
 * Earlier versions were rose (too feminine for the brief), then espresso and
 * amber (which read as Halloween), then bone and ink with no chrome colour at
 * all. That last one existed to keep 300+ colourful nail photos the only colour
 * on the page, and the discipline still holds here: the violet lives in the
 * chrome - header, buttons, active states - and never behind the grid. The
 * logo gets away with it for the same reason, being mostly black.
 */
:root {
  --bg: #08060c;
  --bg-soft: #120c1c;
  --surface: #130d1d;
  --surface-2: #1b1329;
  --line: #3b2a55;
  --line-soft: #271b3b;
  --ink: #f3e9fb;
  --ink-2: #b6a3cc;
  --ink-3: #8272a0;
  --accent: #c86ae8;
  --accent-ink: #12061c;
  --accent-soft: #2e1745;
  --gold: #c86ae8;
  /* Status colours keep their hue: these are signals, not decoration, and a
     desaturated "danger" is a danger nobody notices. */
  --ok: #7fb894;
  --warn: #cbb083;
  --danger: #d98a7e;
  /* the one loud colour: tag group headers, where it cuts against the purple */
  --neon: #39ff14;

  /*
   * Hard edges. These were 14px and 999px pills, which is the visual language
   * of a friendly SaaS dashboard and fought the brief harder than the colours
   * did. Almost-square corners read as a studio, not a signup form.
   */
  --radius: 3px;
  --radius-sm: 2px;
  --radius-pill: 2px;

  /* Flat. Depth here came from soft drop shadows; it now comes from contrast. */
  --shadow: none;
  --shadow-sm: none;

  --font: "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  /* Headings are heavy sans, not a serif - the serif read as bridal-boutique. */
  --display: "Segoe UI Semibold", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  --serif: var(--display);

  /* How strongly the motif shows wherever it is used. */
  --motif-ink: #a855f7;
  --motif-opacity: .3;
}

/* ------------------------------------------------------------------ *
 * Motif
 *
 * Crescent moons and four-point sparkles, taken from the studio's logo. This
 * was a leopard print until the logo arrived; leopard was her favourite thing
 * rather than her brand, and two visual ideas on one page fight.
 *
 * The motif is the signature, so it belongs in the chrome - the header, the
 * hero, rules, empty states - and nowhere near the grid. There are 300+
 * photographs of nail art here and they are already busy; pattern behind them
 * turns every page into noise.
 *
 * It is painted as a *mask* over a solid colour rather than a coloured image,
 * so one 3 KB file recolours itself for any accent. Browsers without mask
 * support simply get no pattern, which is a fine thing to lose.
 *
 * `npm run celestial` redraws it. The old leopard generator is still in
 * scripts/ if it is ever wanted back.
 * ------------------------------------------------------------------ */

.motif {
  -webkit-mask-image: url('/img/celestial.svg');
  mask-image: url('/img/celestial.svg');
  -webkit-mask-repeat: repeat;
  mask-repeat: repeat;
  -webkit-mask-size: 170px;
  mask-size: 170px;
  background-color: var(--motif-ink);
  opacity: var(--motif-opacity);
}

/* Pattern as a backdrop inside a box, sitting under that box's own content. */
.motif-bed { position: relative; isolation: isolate; }
.motif-bed > .motif-layer {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  border-radius: inherit;
}

/* A band of print used instead of a plain rule. */
.motif-rule {
  height: 12px;
  border: 0;
  margin: 1.5rem 0;
  -webkit-mask-size: 96px;
  mask-size: 96px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* Paired with lockScroll() in components.js. `overflow: hidden` alone is not
   enough - it propagates to the viewport and clamps the scroll position to 0,
   so closing a modal dropped you at the top of the feed. Pinning the body with
   an inline negative `top` holds the page still AND remembers where it was. */
body.no-scroll {
  position: fixed;
  left: 0;
  right: 0;
  width: 100%;
  overflow: hidden;
}

/* ------------------------------------------------------------------ *
 * Feels like an app
 *
 * Installed to a home screen this is judged against native apps, and the
 * browser's default touch behaviours are what give it away. Each rule here
 * fixes one specific tell.
 *
 * Note what is deliberately NOT here: `user-scalable=no` in the viewport tag.
 * It is the usual reflex for "stop the zooming", it takes pinch-zoom away from
 * anyone who needs it, and iOS has ignored it since iOS 10 anyway. Fixing the
 * causes below is what actually works.
 * ------------------------------------------------------------------ */

html {
  /* Stops iOS inflating text of its own accord when the phone turns. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* No grey flash box on every tap. */
  -webkit-tap-highlight-color: transparent;
}

body {
  /* Kills pull-to-refresh and the rubber-band bounce past the ends of the
     page. Browser chrome appearing mid-scroll is the biggest "this is a
     website" tell there is. */
  overscroll-behavior-y: none;
}

/* `manipulation` opts out of double-tap-to-zoom on controls, which also
   removes the ~300ms delay browsers add while waiting to see if a second tap
   is coming. Taps feel instant instead of laggy. */
a, button, label, summary,
.btn, .chip, .nav-link, .bottom-link, .tag-btn, .icon-btn {
  touch-action: manipulation;
}

/* Chrome should not be selectable or offer long-press menus - dragging a
   nav label and highlighting it is something apps never do. Content text is
   left alone on purpose so people can still copy a title or a tag. */
.topbar, .bottom-nav, .brand,
.btn, .nav-link, .bottom-link, .field-label, .bottom-icon {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

/* Comfortable thumb targets. Apple's guidance is 44px; the tab bar was landing
   just under it. */
.bottom-link { min-height: 44px; justify-content: center; }

h1, h2, h3 {
  font-family: var(--display);
  font-weight: 800;
  line-height: 1.1;
  margin: 0 0 .4em;
  letter-spacing: -.025em;
}

/* Headlines run big, tight and upper-case. This is the loudest single thing in
   the redesign: set small and sentence-case, the same words read as a tidy
   product page rather than a studio with a point of view. */
h1 {
  font-size: clamp(2rem, 1.3rem + 3.2vw, 3.4rem);
  text-transform: uppercase;
  letter-spacing: -.03em;
}
h2 { font-size: clamp(1.35rem, 1.1rem + 1.1vw, 1.8rem); }
h3 { font-size: 1.06rem; font-family: var(--font); font-weight: 650; letter-spacing: 0; }

/* Small upper-case tracked labels for controls - nav, buttons, the tab bar.
   Deliberately *not* applied to .chip: chips carry tag names, and a tag is
   content rather than a control. "Hand-Painted" shouted as HAND-PAINTED in the
   dashboard while reading normally in the filters and on every pin was the
   inconsistency; sentence case wins because it is also easier to scan 74 of. */
.nav-link,
.btn,
.bottom-link span:last-child {
  text-transform: uppercase;
  letter-spacing: .09em;
}

p { margin: 0 0 .8em; }
a { color: inherit; }

img { max-width: 100%; display: block; }

.muted { color: var(--ink-2); }
.tiny { font-size: .8rem; }
.lede { font-size: 1.08rem; color: var(--ink-2); }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--accent);
  color: var(--accent-ink);
  padding: .6rem 1rem;
  z-index: 100;
  border-radius: 0 0 var(--radius-sm) 0;
}
.skip-link:focus { left: 0; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ------------------------------------------------------------------ *
 * Shell
 * ------------------------------------------------------------------ */

/* A band of print across the very top of every page. This is the site's
   signature and the first thing anyone sees, so it is full strength here -
   unlike the hero, there is no text sitting on it to protect. */
.topbar {
  position: sticky;
  top: 0;
  z-index: 30;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.topbar::before {
  content: "";
  display: block;
  height: 7px;
  -webkit-mask-image: url('/img/celestial.svg');
  mask-image: url('/img/celestial.svg');
  -webkit-mask-repeat: repeat;
  mask-repeat: repeat;
  -webkit-mask-size: 62px;
  mask-size: 62px;
  background-color: var(--gold);
  opacity: .95;
}

.topbar-inner {
  max-width: 1180px;
  margin: 0 auto;
  padding: .7rem 1.1rem;
  display: flex;
  align-items: center;
  gap: 1rem;
}

/* Installed to a home screen the page runs full-bleed, so the status bar and
   the home indicator would otherwise sit on top of the app's own chrome. */
@media (display-mode: standalone) {
  .topbar { padding-top: env(safe-area-inset-top); }
  .topbar-inner,
  .main,
  .site-foot {
    padding-left: max(1.1rem, env(safe-area-inset-left));
    padding-right: max(1.1rem, env(safe-area-inset-right));
  }
  /* no browser back button in standalone, so keep the in-app one prominent */
  .back-link { font-size: .95rem; font-weight: 600; }
}

.brand {
  display: flex;
  align-items: center;
  gap: .6rem;
  text-decoration: none;
  min-width: 0;
}

/* A glowing disc of the motif - the identity in 34 pixels. The full logo is
   not used here: all of its lettering sits inside the circle and turns to mush
   below about 200px, so the header gets the mark and live text instead. */
.brand-mark {
  width: 34px; height: 34px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 50%;
  /* Dark disc, not a pale one: the logo is a lit mark on black, and a bone
     circle in the corner fought that the moment the palette changed. */
  background: #0b0713;
  color: var(--accent);
  font-size: .95rem;
  position: relative;
  isolation: isolate;
  overflow: hidden;
}
/* The mark is an image of her triple moon, not the background tile masked into
   a circle. A repeating pattern cropped to 34px shows whatever fragment happens
   to land there, which reads as specks of dirt rather than as a symbol. */
.brand-mark img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.brand-text { display: flex; flex-direction: column; min-width: 0; }
.brand-text strong {
  font-family: var(--display);
  font-size: 1rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .07em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.brand-text small { color: var(--ink-3); font-size: .74rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.nav-wrap { margin-left: auto; display: flex; align-items: center; gap: .4rem; }
.nav { display: flex; gap: .1rem; }

.nav-link {
  text-decoration: none;
  padding: .42rem .72rem;
  border-radius: var(--radius-pill);
  color: var(--ink-2);
  font-size: .92rem;
  white-space: nowrap;
}
.nav-link:hover { background: var(--bg-soft); color: var(--ink); }
.nav-link.on { background: var(--accent-soft); color: var(--accent); font-weight: 600; }

.nav-owner {
  border: 1px solid var(--line);
  margin-left: .3rem;
}

.menu-toggle { display: none; margin-left: auto; }

.main {
  max-width: 1180px;
  margin: 0 auto;
  padding: 1.4rem 1.1rem 4rem;
  min-height: 60vh;
}

.view { animation: rise .28s ease; }
.view-narrow { max-width: 720px; margin: 0 auto; }

@keyframes rise {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

.site-foot {
  max-width: 1180px;
  margin: 0 auto;
  padding: 2rem 1.1rem 5.5rem;
  border-top: 1px solid var(--line-soft);
  color: var(--ink-2);
  font-size: .88rem;
}

/* ------------------------------------------------------------------ *
 * Hero
 * ------------------------------------------------------------------ */

/* The hero carries the print, fading out to the right so the headline always
   sits on quiet ground no matter how long it runs. */
.hero {
  background: var(--bg-soft);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 1.8rem 1.6rem;
  margin-bottom: 1.4rem;
  position: relative;
  isolation: isolate;
  overflow: hidden;
}
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  -webkit-mask-image: url('/img/celestial.svg');
  mask-image: url('/img/celestial.svg');
  -webkit-mask-repeat: repeat;
  mask-repeat: repeat;
  -webkit-mask-size: 150px;
  mask-size: 150px;
  background-color: var(--motif-ink);
  opacity: .5;
}
/* The print runs at full strength on the right and is wiped out under the
   headline, so it can be bold without ever costing legibility. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(100deg, var(--bg-soft) 38%, color-mix(in srgb, var(--bg-soft) 55%, transparent) 62%, transparent 88%);
  pointer-events: none;
}
.hero p { color: var(--ink-2); max-width: 62ch; margin-bottom: 0; }
.hero-sm { padding: 1.3rem 1.4rem; }
.hero-actions { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 1rem; }

/* ------------------------------------------------------------------ *
 * Buttons
 * ------------------------------------------------------------------ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .45rem;
  padding: .58rem 1.05rem;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: .82rem;
  font-weight: 700;
  text-decoration: none;
  cursor: pointer;
  transition: transform .12s ease, background .16s ease, box-shadow .16s ease;
  box-shadow: var(--shadow-sm);
  border-color: var(--line);
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: none; }
.btn[disabled] { opacity: .55; cursor: default; transform: none; }

.btn-primary { background: var(--accent); color: var(--accent-ink); }
.btn-primary:hover { background: color-mix(in srgb, var(--accent) 88%, black); }
.btn-quiet { background: transparent; border-color: var(--line); color: var(--ink-2); box-shadow: none; }
.btn-quiet:hover { background: var(--bg-soft); color: var(--ink); }
.btn-danger { background: transparent; border-color: color-mix(in srgb, var(--danger) 40%, transparent); color: var(--danger); box-shadow: none; }
.btn-danger:hover { background: color-mix(in srgb, var(--danger) 12%, transparent); }
.btn-sm { padding: .36rem .74rem; font-size: .84rem; }
.btn-lg { padding: .75rem 1.4rem; font-size: 1rem; }

.link-btn {
  background: none;
  border: 0;
  padding: 0;
  color: var(--accent);
  font: inherit;
  font-size: .88rem;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.icon-btn {
  background: none;
  border: 0;
  font-size: 1.35rem;
  line-height: 1;
  color: var(--ink-2);
  cursor: pointer;
  padding: .3rem .5rem;
  border-radius: var(--radius-sm);
}
.icon-btn:hover { background: var(--bg-soft); color: var(--ink); }

.has-badge { position: relative; }
.has-badge::after {
  content: attr(data-badge);
  position: absolute;
  top: -5px; right: -5px;
  min-width: 18px; height: 18px;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--accent-ink);
  font-size: .68rem;
  font-weight: 700;
  display: grid;
  place-items: center;
  padding: 0 4px;
}

/* ------------------------------------------------------------------ *
 * Toolbar + filters
 * ------------------------------------------------------------------ */

.toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: .8rem;
  align-items: center;
  margin-bottom: .9rem;
}
.toolbar-main { display: flex; gap: .5rem; flex: 1 1 320px; min-width: 0; }
.toolbar-side { display: flex; gap: .6rem; align-items: center; }
.search-input { flex: 1; }
.sort-label { display: flex; align-items: center; gap: .45rem; font-size: .86rem; color: var(--ink-2); }
.sort-label select { width: auto; }

.filter-panel {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 1.1rem;
  margin-bottom: 1rem;
  box-shadow: var(--shadow-sm);
  display: grid;
  gap: .9rem;
}

.filter-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: .8rem;
}

.active-filters { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; margin-bottom: .7rem; }
.result-count { margin-bottom: .9rem; font-size: .9rem; }

.chips { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; }

.chip {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .22rem .6rem;
  border-radius: var(--radius-pill);
  background: var(--bg-soft);
  border: 1px solid var(--line-soft);
  font-size: .8rem;
  color: var(--ink-2);
  white-space: nowrap;
}
.chip-link { text-decoration: none; }
.chip-link:hover { background: var(--accent-soft); color: var(--accent); }
.chip-removable { cursor: pointer; font: inherit; font-size: .8rem; }
.chip-removable:hover { border-color: var(--accent); color: var(--accent); }
.chip-x { font-size: .95rem; line-height: 1; opacity: .7; }

.swatch {
  width: 12px; height: 12px;
  border-radius: 50%;
  display: inline-block;
  border: 1px solid rgba(0, 0, 0, .12);
  flex: none;
}
.swatch-row { display: inline-flex; gap: 3px; }

.pill-picker { display: flex; flex-wrap: wrap; gap: .35rem; }

.pill {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .3rem .68rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink-2);
  font: inherit;
  font-size: .82rem;
  cursor: pointer;
}
.pill:hover { border-color: var(--accent); }
.pill.on { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.pill.on .swatch { border-color: rgba(255, 255, 255, .5); }

/* ------------------------------------------------------------------ *
 * Grid + cards
 * ------------------------------------------------------------------ */

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 1.1rem;
}
.grid-sm { grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); }

.card {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  display: flex;
  flex-direction: column;
  box-shadow: var(--shadow-sm);
  transition: transform .16s ease, box-shadow .16s ease;
}
.card:hover { transform: translateY(-3px); box-shadow: var(--shadow); }

.card-media {
  position: relative;
  aspect-ratio: 4 / 5;
  background: var(--bg-soft);
  overflow: hidden;
  border: 0;
  padding: 0;
  width: 100%;
  cursor: pointer;
}
.card-media img { width: 100%; height: 100%; object-fit: cover; }
.card-media-blank {
  width: 100%; height: 100%;
  display: grid; place-items: center;
  color: var(--ink-3);
  font-size: .85rem;
}
.card-media-blank.tall { aspect-ratio: 4 / 5; border-radius: var(--radius); }
.as-button { background: var(--bg-soft); }

.ribbon {
  position: absolute;
  top: .55rem; left: .55rem;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  padding: .16rem .5rem;
  border-radius: var(--radius-pill);
}
.ribbon-alt { background: var(--gold); color: #241a08; }
.ribbon-warn { background: var(--warn); color: #fff; top: auto; bottom: .55rem; }

.card-body { padding: .75rem .85rem .85rem; display: flex; flex-direction: column; gap: .3rem; flex: 1; }
.card-title { margin: 0; font-size: .98rem; }
.card-meta { margin: 0; font-size: .8rem; color: var(--ink-3); }
.card-note { margin: 0; font-size: .86rem; color: var(--ink-2); }
.card-foot { margin-top: auto; display: flex; align-items: center; justify-content: space-between; gap: .5rem; padding-top: .35rem; }
.card-price { font-weight: 650; font-size: .9rem; }
.card-actions { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; margin-top: .4rem; }
.card-admin { display: flex; gap: .35rem; padding: 0 .85rem .85rem; flex-wrap: wrap; }

.like {
  position: absolute;
  right: .5rem; bottom: .5rem;
  display: inline-flex;
  align-items: center;
  gap: .2rem;
  border: 0;
  border-radius: var(--radius-pill);
  padding: .22rem .55rem;
  background: rgba(255, 255, 255, .88);
  color: #6b5b60;
  font: inherit;
  font-size: .8rem;
  cursor: pointer;
  backdrop-filter: blur(4px);
}
.like .heart { font-size: .95rem; line-height: 1; }
.like.on { background: var(--accent); color: #fff; }
.like:hover { transform: scale(1.05); }

/* ------------------------------------------------------------------ *
 * Menu list
 * ------------------------------------------------------------------ */

.menu-note {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .8rem;
  justify-content: space-between;
  background: var(--surface-2);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: .9rem 1.1rem;
  margin-bottom: 1.2rem;
}
.menu-note p { margin: 0; color: var(--ink-2); font-size: .92rem; }

.menu-list { display: grid; gap: .7rem; margin-bottom: 1.6rem; }

.menu-item {
  display: grid;
  grid-template-columns: 84px 1fr auto;
  gap: 1rem;
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: .8rem;
  box-shadow: var(--shadow-sm);
}
.menu-thumb {
  width: 84px; height: 100px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--bg-soft);
  display: grid;
  place-items: center;
  color: var(--ink-3);
}
.menu-thumb img { width: 100%; height: 100%; object-fit: cover; }
.menu-info { min-width: 0; display: flex; flex-direction: column; gap: .25rem; }
.menu-title { font-weight: 650; text-decoration: none; font-size: 1rem; }
.menu-title:hover { color: var(--accent); }
.menu-meta { margin: 0; font-size: .8rem; color: var(--ink-3); }
.menu-desc {
  margin: 0;
  font-size: .88rem;
  color: var(--ink-2);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.menu-tags { display: flex; flex-wrap: wrap; gap: .3rem; align-items: center; }
.menu-action { display: flex; flex-direction: column; align-items: flex-end; gap: .3rem; }
.menu-price { font-weight: 700; font-size: 1.05rem; }
.menu-dur { font-size: .8rem; color: var(--ink-3); }

/* ------------------------------------------------------------------ *
 * Detail
 * ------------------------------------------------------------------ */

.back-link { display: inline-block; margin-bottom: .9rem; font-size: .88rem; color: var(--ink-2); text-decoration: none; }
.back-link:hover { color: var(--accent); }

.detail { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); gap: 2rem; align-items: start; }
.detail-media { position: sticky; top: 5rem; }
.detail-img { width: 100%; border-radius: var(--radius); box-shadow: var(--shadow); background: var(--bg-soft); }
.thumb-row { display: flex; gap: .5rem; margin-top: .6rem; flex-wrap: wrap; }
.thumb {
  width: 64px; height: 78px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  border: 1px solid var(--line);
  background: none;
  padding: 0;
  cursor: pointer;
}
.thumb img { width: 100%; height: 100%; object-fit: cover; }
.detail-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
.detail-head .like { position: static; background: var(--bg-soft); }
.detail-desc { color: var(--ink-2); }
.detail-block { margin: 1rem 0; }
.detail-block h3 { font-size: .82rem; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-3); }
.detail-cta { display: flex; flex-wrap: wrap; gap: .6rem; margin: 1.3rem 0 .8rem; }
.credit { font-size: .84rem; color: var(--gold); margin-top: -.3rem; }

.facts {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: .35rem 1rem;
  margin: 1rem 0;
  font-size: .92rem;
}
.facts dt { color: var(--ink-3); }
.facts dd { margin: 0; font-weight: 550; }

/* ------------------------------------------------------------------ *
 * Forms
 * ------------------------------------------------------------------ */

.card-form {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 1.2rem;
  display: grid;
  gap: .95rem;
  box-shadow: var(--shadow-sm);
}

.field { display: flex; flex-direction: column; gap: .32rem; min-width: 0; }
.field-label { font-size: .82rem; font-weight: 600; color: var(--ink-2); }
.field-hint { font-size: .78rem; color: var(--ink-3); }

/*
 * 16px is not a style choice - it is the fix for the zooming.
 *
 * iOS Safari force-zooms the whole page whenever you focus a text field whose
 * font-size is below 16px, and it does not zoom back out afterwards. At the
 * previous .94rem (15px) that fired on every tap of the search box or any form
 * field, which left the layout sitting wrong until it was pinched back by hand.
 * Anything typed into must stay at 16px or larger.
 */
input, select, textarea { font-size: 16px; }

.input {
  width: 100%;
  padding: .58rem .7rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--ink);
  font: inherit;
  font-size: 16px;
}
.input:focus { border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px var(--accent-soft); }
.textarea { resize: vertical; min-height: 88px; }
.select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--ink-3) 50%), linear-gradient(135deg, var(--ink-3) 50%, transparent 50%); background-position: right 14px center, right 9px center; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; padding-right: 2rem; }

.check { display: flex; align-items: flex-start; gap: .55rem; font-size: .9rem; cursor: pointer; }
.check input { margin-top: .25rem; accent-color: var(--accent); width: 16px; height: 16px; }
.toggles { display: grid; gap: .5rem; }
.consent {
  background: var(--accent-soft);
  border-radius: var(--radius-sm);
  padding: .8rem .9rem;
}
.consent .field-hint { display: block; margin: .45rem 0 0 2.1rem; }

/* an optional block of fields nested inside a form, e.g. "coming in soon?" */
.sub-form {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  padding: .3rem .9rem .9rem;
  margin: 0;
  display: grid;
  gap: .5rem;
}
.sub-form legend {
  padding: 0 .4rem;
  font-size: .82rem;
  font-weight: 600;
  color: var(--ink-2);
}
.sub-form .field-hint { margin: 0; }

.form-actions { display: flex; flex-wrap: wrap; gap: .6rem; margin: 1rem 0 1.6rem; }
.form-error { color: var(--danger); font-size: .88rem; margin: 0; }

.inline-field { display: flex; align-items: center; gap: .4rem; font-size: .82rem; color: var(--ink-2); }
.inline-field.grow { flex: 1 1 220px; }
.inline-field select, .inline-field input { width: auto; flex: 1; min-width: 120px; }

.kind-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: .8rem; margin-bottom: 1.2rem; }
.kind-card {
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: .3rem;
  padding: 1rem 1.1rem;
  border-radius: var(--radius);
  border: 1.5px solid var(--line);
  background: var(--surface);
  font: inherit;
  cursor: pointer;
  color: var(--ink-2);
}
.kind-card strong { color: var(--ink); font-size: 1rem; }
.kind-card span { font-size: .86rem; }
.kind-card:hover { border-color: var(--accent); }
.kind-card.on { border-color: var(--accent); background: var(--accent-soft); }

/* photo picker */
.photo-picker { display: grid; gap: .5rem; }
.photo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: .55rem; }
.photo-tile {
  position: relative;
  margin: 0;
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--bg-soft);
  border: 1px solid var(--line-soft);
}
.photo-tile img { width: 100%; height: 100%; object-fit: cover; }
.photo-tile figcaption {
  position: absolute; bottom: 0; left: 0; right: 0;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  font-size: .68rem;
  text-align: center;
  padding: .1rem;
}
.photo-remove {
  position: absolute;
  top: 3px; right: 3px;
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 0;
  background: rgba(0, 0, 0, .6);
  color: #fff;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}
.photo-add {
  aspect-ratio: 4 / 5;
  border: 1.5px dashed var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--ink-2);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .2rem;
  font: inherit;
  font-size: .8rem;
  cursor: pointer;
}
.photo-add:hover { border-color: var(--accent); color: var(--accent); }
.photo-add-mark { font-size: 1.5rem; line-height: 1; }

.chosen-set {
  display: flex;
  gap: 1rem;
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: .9rem;
  margin-bottom: 1.1rem;
}
.chosen-set img { width: 84px; height: 100px; object-fit: cover; border-radius: var(--radius-sm); }
.chosen-set h3 { margin: 0; }

/* ------------------------------------------------------------------ *
 * Lists / rows
 * ------------------------------------------------------------------ */

.stack { display: grid; gap: .8rem; }

.row-card {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: .9rem;
  box-shadow: var(--shadow-sm);
}
.row-thumb {
  width: 88px;
  height: 110px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  flex: none;
  background: var(--bg-soft);
  border: 0;
  padding: 0;
  overflow: hidden;
  cursor: pointer;
}
.row-thumb img { width: 100%; height: 100%; object-fit: cover; }
.avatar {
  width: 44px; height: 44px;
  flex: none;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: linear-gradient(140deg, var(--accent), var(--gold));
  color: #fff;
  font-weight: 650;
  font-size: .9rem;
  letter-spacing: .02em;
}

.static-field {
  margin: 0;
  padding: .58rem .7rem;
  border: 1px dashed var(--line);
  border-radius: var(--radius-sm);
  color: var(--ink-2);
  font-size: .94rem;
  background: var(--surface-2);
}

.row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .3rem; }
.row-main h3 { margin: 0; }
.row-main p { margin: 0; font-size: .88rem; }
.row-head { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.contact { font-size: .9rem; }
.contact a { color: var(--accent); }

.badge {
  font-size: .7rem;
  text-transform: uppercase;
  letter-spacing: .05em;
  font-weight: 700;
  padding: .12rem .5rem;
  border-radius: var(--radius-pill);
  background: var(--bg-soft);
  color: var(--ink-2);
  border: 1px solid var(--line-soft);
}
.badge-pending, .badge-new { background: var(--accent-soft); color: var(--accent); border-color: transparent; }
.badge-approved, .badge-booked { background: color-mix(in srgb, var(--ok) 18%, transparent); color: var(--ok); border-color: transparent; }
.badge-rejected, .badge-declined { background: color-mix(in srgb, var(--danger) 15%, transparent); color: var(--danger); border-color: transparent; }
.badge-contacted { background: color-mix(in srgb, var(--warn) 18%, transparent); color: var(--warn); border-color: transparent; }

.status { font-size: .88rem; font-weight: 600; }
.status-pending { color: var(--warn); }
.status-approved { color: var(--ok); }
.status-rejected { color: var(--ink-3); }

.sub-details { display: grid; gap: .7rem; margin: .6rem 0; padding: .8rem; background: var(--surface-2); border-radius: var(--radius-sm); }

/* ------------------------------------------------------------------ *
 * Dashboard
 * ------------------------------------------------------------------ */

.tabs {
  display: flex;
  gap: .3rem;
  overflow-x: auto;
  border-bottom: 1px solid var(--line-soft);
  margin-bottom: 1.2rem;
  padding-bottom: .2rem;
}
.tab {
  border: 0;
  background: none;
  font: inherit;
  font-size: .93rem;
  color: var(--ink-2);
  padding: .5rem .85rem;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  cursor: pointer;
  white-space: nowrap;
  border-bottom: 2px solid transparent;
}
.tab:hover { background: var(--bg-soft); }
.tab.on { color: var(--accent); border-bottom-color: var(--accent); font-weight: 650; }

.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: .8rem; margin-bottom: 1.2rem; }
.tile {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: .15rem;
  box-shadow: var(--shadow-sm);
}
.tile-warn { border-color: color-mix(in srgb, var(--accent) 45%, transparent); background: var(--accent-soft); }
.tile-value { font-family: var(--serif); font-size: 2rem; line-height: 1.1; }
.tile-label { font-size: .88rem; font-weight: 600; }
.tile-hint { font-size: .78rem; color: var(--ink-3); }

.section-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  margin: 1.6rem 0 .8rem;
  flex-wrap: wrap;
}
.section-head h2 { margin: 0; }
.section-head p { margin: 0; font-size: .88rem; }

.notice {
  margin-top: 1.4rem;
  padding: 1rem 1.1rem;
  border-radius: var(--radius);
  border: 1px dashed var(--line);
  background: var(--surface-2);
  display: flex;
  flex-wrap: wrap;
  gap: .8rem;
  align-items: center;
  justify-content: space-between;
}
.notice p { margin: 0; font-size: .9rem; color: var(--ink-2); }

/* ------------------------------------------------------------------ *
 * Modal / lightbox
 * ------------------------------------------------------------------ */

.backdrop {
  position: fixed;
  inset: 0;
  background: rgba(30, 18, 22, .55);
  backdrop-filter: blur(3px);
  display: grid;
  place-items: center;
  padding: 1rem;
  z-index: 60;
  animation: fade .2s ease;
}
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

.modal {
  background: var(--bg);
  border-radius: var(--radius);
  width: min(560px, 100%);
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  box-shadow: 0 30px 70px rgba(0, 0, 0, .35);
  overflow: hidden;
}
.modal-wide { width: min(880px, 100%); }
.modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: .9rem 1.1rem;
  border-bottom: 1px solid var(--line-soft);
}
.modal-head h2 { margin: 0; font-size: 1.15rem; }
.modal-body { padding: 1.1rem; overflow-y: auto; }
.modal-foot {
  display: flex;
  gap: .6rem;
  justify-content: flex-end;
  padding: .8rem 1.1rem;
  border-top: 1px solid var(--line-soft);
  background: var(--surface-2);
}

.lightbox { position: relative; display: grid; place-items: center; }
.lightbox-img { max-height: 74vh; width: auto; border-radius: var(--radius-sm); }
.lightbox-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  border: 0;
  background: rgba(0, 0, 0, .45);
  color: #fff;
  font-size: 2rem;
  line-height: 1;
  width: 44px; height: 44px;
  border-radius: 50%;
  cursor: pointer;
}
.lightbox-nav.prev { left: .4rem; }
.lightbox-nav.next { right: .4rem; }
.lightbox-foot { display: flex; gap: .8rem; justify-content: center; color: var(--ink-2); font-size: .85rem; padding-top: .6rem; }

/* ------------------------------------------------------------------ *
 * Feedback
 * ------------------------------------------------------------------ */

.loading, .boot {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .6rem;
  padding: 3rem 1rem;
  color: var(--ink-2);
  font-size: .92rem;
  grid-column: 1 / -1;
}
.boot { flex-direction: column; min-height: 60vh; }

.spin {
  width: 18px; height: 18px;
  border-radius: 50%;
  border: 2px solid var(--line);
  border-top-color: var(--accent);
  animation: spin .8s linear infinite;
  display: inline-block;
  flex: none;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* An empty grid is the one place a big stretch of print costs nothing, since
   there is no photography to compete with. */
.empty {
  grid-column: 1 / -1;
  text-align: center;
  padding: 3rem 1.2rem;
  color: var(--ink-2);
  background: var(--surface-2);
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  position: relative;
  isolation: isolate;
  overflow: hidden;
}
.empty::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  -webkit-mask-image: url('/img/celestial.svg');
  mask-image: url('/img/celestial.svg');
  -webkit-mask-repeat: repeat;
  mask-repeat: repeat;
  -webkit-mask-size: 150px;
  mask-size: 150px;
  background-color: var(--motif-ink);
  opacity: calc(var(--motif-opacity) * .7);
}
.empty-mark { font-size: 2rem; color: var(--accent); }
.empty h3 { font-family: var(--serif); font-size: 1.25rem; margin: .3rem 0 .4rem; }
.empty p { max-width: 46ch; margin: 0 auto 1rem; font-size: .92rem; }

.more-wrap { display: flex; justify-content: center; margin: 1.6rem 0; }

.thanks { text-align: center; padding: 2rem 1rem; }
.thanks-mark {
  width: 64px; height: 64px;
  margin: 0 auto 1rem;
  border-radius: 50%;
  background: var(--ok);
  color: #fff;
  font-size: 1.8rem;
  display: grid;
  place-items: center;
}
.thanks-img { width: 180px; border-radius: var(--radius); margin: 1rem auto; box-shadow: var(--shadow); }
.thanks .hero-actions { justify-content: center; }

.toasts {
  position: fixed;
  left: 50%;
  bottom: 5.2rem;
  transform: translateX(-50%);
  display: grid;
  gap: .5rem;
  z-index: 90;
  width: min(420px, calc(100vw - 2rem));
}
.toast {
  background: var(--ink);
  color: var(--bg);
  padding: .7rem 1rem;
  border-radius: var(--radius-sm);
  font-size: .9rem;
  box-shadow: var(--shadow);
  animation: rise .22s ease;
}
.toast-error { background: var(--danger); color: #fff; }
.toast-ok { background: var(--ok); color: #fff; }
.toast.leaving { opacity: 0; transition: opacity .3s ease; }

/* ------------------------------------------------------------------ *
 * Bottom nav (small screens)
 * ------------------------------------------------------------------ */

.bottom-nav { display: none; }

@media (max-width: 860px) {
  .menu-toggle { display: block; }
  .nav-wrap {
    display: none;
    position: absolute;
    top: 100%;
    left: 0; right: 0;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    padding: .6rem 1rem 1rem;
    flex-direction: column;
    align-items: stretch;
    gap: .2rem;
    box-shadow: var(--shadow);
  }
  .topbar.menu-open .nav-wrap { display: flex; }
  .topbar-inner { position: relative; }
  .nav { flex-direction: column; }
  .nav-link { padding: .6rem .8rem; border-radius: var(--radius-sm); }
  .nav-owner { margin: .4rem 0 0; text-align: center; }

  .detail { grid-template-columns: 1fr; gap: 1.2rem; }
  .detail-media { position: static; }

  .menu-item { grid-template-columns: 68px 1fr; grid-template-areas: "thumb info" "action action"; }
  .menu-thumb { grid-area: thumb; width: 68px; height: 82px; }
  .menu-info { grid-area: info; }
  .menu-action { grid-area: action; flex-direction: row; align-items: center; justify-content: space-between; }

  .row-card { flex-wrap: wrap; }
  .row-thumb { width: 72px; height: 90px; }

  .bottom-nav {
    display: flex;
    position: fixed;
    bottom: 0; left: 0; right: 0;
    background: color-mix(in srgb, var(--surface) 94%, transparent);
    backdrop-filter: blur(10px);
    border-top: 1px solid var(--line-soft);
    padding: .3rem .2rem calc(.3rem + env(safe-area-inset-bottom));
    z-index: 40;
  }
  .bottom-link {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .1rem;
    text-decoration: none;
    color: var(--ink-3);
    font-size: .68rem;
    padding: .35rem 0;
  }
  .bottom-link.on { color: var(--accent); }
  .bottom-icon { font-size: 1.1rem; line-height: 1; }
  .toasts { bottom: 5.6rem; }

  /* Get the tab bar out of the way while typing, the way apps do. Without
     this it sits on top of the on-screen keyboard, or hovers over the field
     being filled in. Browsers without :has() simply keep the bar visible. */
  body:has(input:focus, textarea:focus) .bottom-nav { display: none; }
}

@media (max-width: 520px) {
  .main { padding: 1rem .8rem 4rem; }
  .grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: .7rem; }
  .hero { padding: 1.2rem 1rem; }
  .card-form { padding: 1rem .9rem; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
}

/* ------------------------------------------------------------------ *
 * Pinterest-style feed
 * ------------------------------------------------------------------ */

.masonry {
  column-count: 4;
  column-gap: 1rem;
}
@media (max-width: 1100px) { .masonry { column-count: 3; } }
@media (max-width: 760px)  { .masonry { column-count: 2; column-gap: .7rem; } }
@media (max-width: 330px)  { .masonry { column-count: 1; } }

.masonry > * {
  break-inside: avoid;
  margin-bottom: 1rem;
}

.pin {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: transform .16s ease, box-shadow .16s ease;
}
.pin:hover { transform: translateY(-2px); box-shadow: var(--shadow); }
.pin-featured { border-color: color-mix(in srgb, var(--accent) 45%, transparent); }

.pin-media-wrap { position: relative; background: var(--bg-soft); }
.pin-media { display: block; }
.pin-media img { width: 100%; height: auto; display: block; }

.save-btn {
  position: absolute;
  top: .5rem; right: .5rem;
  border: 0;
  border-radius: var(--radius-pill);
  padding: .38rem .85rem;
  background: var(--accent);
  color: var(--accent-ink);
  font: inherit;
  font-size: .84rem;
  font-weight: 600;
  cursor: pointer;
  opacity: 0;
  transition: opacity .15s ease;
  box-shadow: var(--shadow-sm);
}
.pin:hover .save-btn, .save-btn:focus-visible { opacity: 1; }
.save-btn.on { background: var(--surface); color: var(--ink-2); }
@media (hover: none) { .save-btn { opacity: 1; } }

.pin-body { padding: .6rem .75rem .75rem; display: flex; flex-direction: column; gap: .35rem; }
.pin-title { font-weight: 650; font-size: .95rem; text-decoration: none; }
.pin-title:hover { color: var(--accent); }
.pin-tags { display: flex; flex-wrap: wrap; gap: .25rem; }
.pin-foot { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }

/* ------------------------------------------------------------------ *
 * Boards
 * ------------------------------------------------------------------ */

.board-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1rem;
}

.board-card {
  text-decoration: none;
  color: inherit;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  box-shadow: var(--shadow-sm);
  display: block;
}
.board-card:hover { box-shadow: var(--shadow); }

.board-mosaic {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-auto-rows: 84px;
  gap: 2px;
  background: var(--bg-soft);
  min-height: 168px;
}
.board-mosaic img { width: 100%; height: 100%; object-fit: cover; }
.board-mosaic > :first-child:nth-last-child(1) { grid-column: 1 / -1; grid-row: 1 / -1; }
.board-meta { padding: .65rem .8rem .8rem; }
.board-meta h3 { margin: 0 0 .15rem; }

.board-choices { display: grid; gap: .4rem; margin-bottom: .9rem; max-height: 45vh; overflow-y: auto; }
.board-choice {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  width: 100%;
  padding: .7rem .85rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.board-choice:hover { border-color: var(--accent); background: var(--accent-soft); }
.board-choice-name { font-weight: 600; }
.new-board-row { display: flex; gap: .5rem; align-items: center; border-top: 1px solid var(--line-soft); padding-top: .9rem; }
.new-board-row .input { flex: 1; }

/* ------------------------------------------------------------------ *
 * Tags
 * ------------------------------------------------------------------ */

.tag-groups { display: grid; gap: .8rem; }

/* Folding groups (Explore): a hard-edged row that opens on tap, with a count
   of what is picked inside so nothing chosen is ever out of sight. */
.tag-group-fold { border: 1px solid var(--line-soft); border-radius: var(--radius-sm); background: var(--surface); }
.tag-group-fold > summary {
  margin: 0;
  padding: .65rem .8rem;
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: .5rem;
  user-select: none;
  /* neon against the purple: these are the things you tap */
  color: var(--neon);
  font-size: .8rem;
}
.tag-group-fold > summary::-webkit-details-marker { display: none; }
.tag-group-fold > summary::before {
  content: '';
  width: .45rem;
  height: .45rem;
  border-right: 2px solid var(--neon);
  border-bottom: 2px solid var(--neon);
  transform: rotate(-45deg);
  transition: transform .15s ease;
  flex: 0 0 auto;
}
.tag-group-fold[open] > summary::before { transform: rotate(45deg); }
.tag-group-fold[open] > summary { text-shadow: 0 0 10px color-mix(in srgb, var(--neon) 55%, transparent); }
.tag-group-fold > .pill-picker { padding: 0 .8rem .8rem; }
/* top-level sections of the Explore filter panel: a touch heavier, nested groups inside */
.filter-fold { background: var(--surface-2); margin-bottom: .55rem; }
.filter-fold > summary { font-size: .84rem; color: var(--ink); padding: .75rem .85rem; }
.filter-fold > .tag-groups, .filter-fold > .filter-row, .filter-fold > .pill-picker { padding: 0 .7rem .75rem; }
.filter-fold > .filter-row { margin: 0; }
.filter-fold .tag-group-fold { background: var(--surface); }

/* Tags & colours: destination picker for filing tags, and chips that move on tap */
.move-bar { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .8rem; padding: .6rem .8rem; border: 1px solid var(--line-soft); border-left: 2px solid var(--accent); background: var(--surface-2); border-radius: var(--radius-sm); }
.move-bar .select, .move-bar select { flex: 1 1 12rem; min-width: 0; }
.chip-move { padding: 0; overflow: hidden; }
.chip-move .chip-body { all: unset; cursor: pointer; padding: .3rem .25rem .3rem .7rem; }
.chip-move .chip-body:hover { color: var(--accent); }
.chip-move .chip-x { all: unset; cursor: pointer; padding: .3rem .6rem .3rem .35rem; color: var(--ink-3); }
.chip-move .chip-x:hover { color: var(--danger); }
.tag-group-fold > .chips { padding: 0 .8rem .8rem; }
.tag-group-count {
  margin-left: auto;
  min-width: 1.35rem;
  padding: .05rem .4rem;
  text-align: center;
  background: var(--accent);
  color: var(--accent-ink);
  border-radius: var(--radius-pill);
  font-size: .72rem;
  letter-spacing: 0;
}
.tag-group-name {
  margin: 0 0 .3rem;
  font-size: .72rem;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--ink-3);
  font-family: var(--font);
  font-weight: 700;
}

/* ------------------------------------------------------------------ *
 * Tag & tidy
 * ------------------------------------------------------------------ */

.tidy-stage { margin-top: .8rem; }
.tidy-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); gap: 1.2rem; align-items: start; }
@media (max-width: 860px) { .tidy-grid { grid-template-columns: 1fr; } }
.tidy-photo { width: 100%; border-radius: var(--radius); box-shadow: var(--shadow); }
.editor-preview { width: 100%; max-height: 40vh; object-fit: contain; border-radius: var(--radius-sm); background: var(--bg-soft); }

/* ------------------------------------------------------------------ *
 * The landing feed
 *
 * One narrow column, big photos, everything else out of the way. The card has
 * no border and no shadow on purpose - the photos supply all the contrast, and
 * chrome between them is what makes a feed tiring to scroll.
 * ------------------------------------------------------------------ */

/* 500px matches the stored photo width exactly, so nothing is upscaled */
.view-feed { max-width: 500px; margin: 0 auto; }

.feed-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.4rem;
}
.feed-heading {
  font-size: clamp(1.35rem, 1.1rem + 1vw, 1.8rem);
  margin: 0;
}
.feed-top-actions { display: flex; gap: .5rem; }

.feed { display: flex; flex-direction: column; gap: 2.6rem; }

.feed-card { display: flex; flex-direction: column; gap: .7rem; }

.feed-head { display: flex; align-items: center; gap: .6rem; }
.feed-who { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.feed-who strong { font-size: .92rem; }

.avatar-sm { width: 34px; height: 34px; font-size: .78rem; }

.feed-photo {
  display: block;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-soft);
  line-height: 0;
}
.feed-photo img {
  width: 100%;
  height: auto;
  display: block;
  transition: transform .5s cubic-bezier(.2, .7, .3, 1);
}
.feed-photo:hover img { transform: scale(1.015); }

.feed-actions { display: flex; align-items: center; gap: .3rem; }

.act {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  border: 0;
  background: none;
  padding: .35rem .5rem;
  border-radius: var(--radius-pill);
  font: inherit;
  font-size: .88rem;
  color: var(--ink-2);
  cursor: pointer;
  text-decoration: none;
  transition: color .15s ease, background .15s ease;
}
.act:hover { background: var(--bg-soft); color: var(--ink); }
.act-icon { font-size: 1.15rem; line-height: 1; }
.act-count { font-variant-numeric: tabular-nums; }
.act-like.on { color: var(--accent); }
.act-save.on { color: var(--gold); }
.act-report { margin-left: auto; opacity: .45; }
.act-report:hover { opacity: 1; color: var(--danger); }

/* a small kick when a like lands, so it feels like it registered */
@keyframes heart-pop {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.45); }
  100% { transform: scale(1); }
}
.act-icon.pop { animation: heart-pop .32s ease; }

.feed-body { display: flex; flex-direction: column; gap: .35rem; }
.feed-title { font-weight: 650; text-decoration: none; font-size: .98rem; }
.feed-title:hover { color: var(--accent); }
.feed-caption { margin: 0; color: var(--ink-2); font-size: .92rem; }
/* Attribution reads as a quiet byline, not as body copy. */
.feed-credit { margin: 0; color: var(--gold); font-size: .84rem; font-style: italic; }
.feed-tags { display: flex; flex-wrap: wrap; gap: .4rem; }
.feed-tag {
  text-decoration: none;
  font-size: .84rem;
  color: var(--accent);
}
.feed-tag:hover { text-decoration: underline; text-underline-offset: 3px; }
.feed-stats { margin: .1rem 0 0; }

.feed-sentinel { display: flex; justify-content: center; padding: 2.5rem 0 1rem; }
.feed-end { margin: 0; }

@media (max-width: 620px) {
  .view-feed { max-width: none; }
  .feed { gap: 2rem; }
  /* full-bleed photos on a phone, the way a feed should look */
  .feed-photo { border-radius: 0; margin-left: -.8rem; margin-right: -.8rem; }
  .feed-photo img { width: calc(100% + 1.6rem); }
}

/* ------------------------------------------------------------------ *
 * Crop step
 * ------------------------------------------------------------------ */

.crop-wrap { display: grid; gap: .7rem; }

/* The frame is the crop. The image is moved behind it and everything outside
   is clipped, so what you see is exactly what gets uploaded. */
.crop-frame {
  position: relative;
  overflow: hidden;
  /* Height is capped by driving the WIDTH from the aspect ratio. Using
     `max-height` instead silently squashed the frame - a 4:5 "Portrait" came
     out at 0.98:1 - so the shape buttons did not do what they said. */
  --crop-ar: 0.8;
  aspect-ratio: var(--crop-ar);
  width: min(100%, calc(58vh * var(--crop-ar)));
  margin: 0 auto;
  background: #000;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  cursor: grab;
  touch-action: none;      /* we handle the dragging ourselves */
  user-select: none;
}
.crop-frame:active { cursor: grabbing; }

.crop-img {
  position: absolute;
  top: 0;
  left: 0;
  transform-origin: 0 0;
  max-width: none;          /* the global img rule would fight the transform */
  will-change: transform;
  pointer-events: none;
}

.crop-zoom { width: 100%; accent-color: var(--accent); }

.crop-shapes { display: flex; flex-wrap: wrap; gap: .35rem; justify-content: center; }
.crop-shapes .chip { cursor: pointer; }
.crop-shapes .chip.on {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: var(--accent);
}

/* ------------------------------------------------------------------ *
 * Nested boards + save picker
 * ------------------------------------------------------------------ */

/* Boards sitting inside another are indented and slightly smaller, so the
   grouping is legible at a glance without a tree widget. */
.board-children {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: .7rem;
  padding-left: 1.1rem;
  margin: -.2rem 0 .5rem;
  border-left: 2px solid var(--line);
}
.board-card-parent .board-meta h3::after {
  content: " ▾";
  color: var(--ink-3);
  font-weight: 400;
}

.save-picker { display: grid; gap: .6rem; }
.save-picker .board-choices { max-height: 46vh; overflow-y: auto; }

/* Already-saved boards stay visible but stop looking like a fresh action. */
.board-choice-has { opacity: .62; }
.board-choice-parent { color: var(--ink-3); font-weight: 400; }

/* Native colour picker, sized to sit beside a text input in a form row. */
.color-input {
  width: 54px;
  flex: none;
  padding: .2rem;
  cursor: pointer;
}

/* Author/studio actions sit apart from the main Save call to action, so
   "Delete" is never adjacent to the button everyone else is aiming for. */
.detail-owner-actions {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line-soft);
}

/* Multi-select rows in the "what is inside this board" picker. */
.board-choice-on {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.board-choice-tick {
  color: var(--accent);
  font-weight: 700;
  width: 1rem;
  text-align: right;
}

/* ------------------------------------------------------------------ *
 * Glow
 *
 * The rim-light is the single most recognisable thing about the logo, and it
 * is what makes the chrome read as the same world rather than a violet
 * repaint. Kept to three places on purpose - the primary action, the brand
 * mark and the active tab. Glow on every surface stops meaning anything, and
 * a page of halos behind photographs is exhausting.
 * ------------------------------------------------------------------ */

.btn-primary {
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 55%, transparent),
              0 0 18px color-mix(in srgb, var(--accent) 42%, transparent);
}
.btn-primary:hover {
  box-shadow: 0 0 0 1px var(--accent),
              0 0 26px color-mix(in srgb, var(--accent) 60%, transparent);
}

.brand-mark {
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 70%, transparent),
              0 0 14px color-mix(in srgb, var(--accent) 45%, transparent);
}

.topbar::before { filter: drop-shadow(0 0 5px var(--motif-ink)); }

.bottom-link.on { text-shadow: 0 0 12px color-mix(in srgb, var(--accent) 70%, transparent); }

/* Focus stays visible against the glow rather than competing with it. */
:focus-visible { outline-color: var(--accent); }

/* ------------------------------------------------------------------ *
 * The full logo
 *
 * Only used where it is large enough for its own lettering to read - About
 * and sign-in. Anywhere smaller gets the mark and live text instead.
 * ------------------------------------------------------------------ */

.logo-block { text-align: center; margin: .5rem 0 1rem; }
.logo-block img {
  width: min(340px, 78%);
  height: auto;
  margin: 0 auto;
  border-radius: 50%;
  /* The file has its black background baked in, so a soft halo stops it
     reading as a black square pasted onto a black page. */
  box-shadow: 0 0 40px color-mix(in srgb, var(--accent) 28%, transparent);
}
.logo-block-sm img { width: min(190px, 55%); }
.logo-tagline { text-align: center; margin-bottom: 1.4rem; }

/* ------------------------------------------------------------------ *
 * Upload guidance
 *
 * Sits under the photo picker rather than above the form: by the time someone
 * is choosing a photo they are already committed, and a wall of rules before
 * the first control is the fastest way to have it skipped.
 * ------------------------------------------------------------------ */

.quality-note {
  border: 1px solid var(--line-soft);
  border-left: 2px solid var(--accent);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  padding: .8rem .95rem;
  margin: -.2rem 0 .2rem;
}
.quality-note h4 {
  margin: 0 0 .4rem;
  font-size: .82rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--accent);
}
.quality-note ul { margin: 0; padding-left: 1.1rem; }
.quality-note li {
  color: var(--ink-2);
  font-size: .86rem;
  margin-bottom: .3rem;
}
.quality-note li:last-child { margin-bottom: 0; }

/* Password reset link, shown on a person's card in the dashboard */
.reset-link {
  display: grid;
  gap: .55rem;
  margin-top: .7rem;
  padding: .8rem .95rem;
  border: 1px solid var(--line-soft);
  border-left: 2px solid var(--accent);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
}
.reset-link-title {
  margin: 0;
  font-size: .82rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--accent);
}
.reset-link .input { width: 100%; font-size: 16px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.reset-link-actions { display: flex; flex-wrap: wrap; gap: .5rem; }
.reset-link .muted { margin: 0; font-size: .84rem; }

/* Delete-account block at the foot of the profile tab */
.danger-zone {
  margin-top: 2rem;
  padding: 1rem 1.1rem 1.1rem;
  border: 1px solid color-mix(in srgb, var(--danger) 35%, transparent);
  border-left: 2px solid var(--danger);
  border-radius: var(--radius-sm);
}
.danger-zone .section-head h2 { color: var(--danger); }
.danger-zone > .muted { margin-top: -.3rem; }

.contact-list { margin: .3rem 0 0; padding-left: 1.1rem; }
.contact-list li { margin-bottom: .3rem; color: var(--ink-2); }

/* Visitors tab: one series of thin bars on a baseline, values on hover */
.bars {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 160px;
  padding: 1.4rem 0 0;
  border-bottom: 1px solid var(--line);
  margin: .4rem 0 .3rem;
}
.bar-col {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
}
.bar-col:hover .bar { background: var(--ink); }
.bar {
  width: 100%;
  min-height: 2px;
  background: var(--accent);
  border-radius: 2px 2px 0 0;
}
.bar-value {
  position: absolute;
  top: -1.3rem;
  font-size: .78rem;
  font-weight: 600;
  color: var(--ink);
}
.bar-label {
  position: absolute;
  bottom: -1.25rem;
  font-size: .68rem;
  color: var(--ink-3);
  white-space: nowrap;
}
.bars-foot { margin: 1.4rem 0 0; }
.data-table { width: 100%; border-collapse: collapse; font-size: .88rem; margin-top: .4rem; }
.data-table th, .data-table td { padding: .42rem .5rem; text-align: right; border-bottom: 1px solid var(--line-soft); }
.data-table th:first-child, .data-table td:first-child { text-align: left; }
.data-table th { color: var(--ink-3); font-weight: 600; font-size: .78rem; text-transform: uppercase; letter-spacing: .06em; }
.data-table tr.is-today td { color: var(--ink); font-weight: 600; }

/* The inline "add your own tag" block, studio only. */
.tag-group-new {
  border-top: 1px solid var(--line-soft);
  padding-top: .7rem;
  margin-top: .3rem;
}
