/* Base visual layer. Component-specific styles live in app.css. */

*,
    *::before,
    *::after {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }

    :root {
      color-scheme: dark;
      --ink: #ffffff;
      --on-ink: #000000;
      --ink-dim: #d9d9df;
      --paper: #000000;
      --card: #000000;
      --field: #000000;
      --neon: #ffffff;
      --sheet-accent: #d6007f;
      --muted: #8f8f98;
      --soft: #0e0e0e;
      --soft-2: #1d1d1d;
      --line: rgba(255, 255, 255, .10);
      --line-mid: rgba(255, 255, 255, .22);
      --line-strong: rgba(255, 255, 255, .55);
      --on-ink-muted: rgba(0, 0, 0, .55);
      --F-display: 'Unbounded', 'Arial Black', sans-serif;
      --F-sans: 'Manrope', 'Helvetica Neue', Arial, sans-serif;
      --F-serif: 'Manrope', 'Helvetica Neue', Arial, sans-serif;
      --F-condensed: 'Unbounded', 'Arial Black', sans-serif;
      --r-pill: 999px;
      --r-card: 18px;
      --r-sm: 12px;
      --panel-w: 460px;
      --top-h: 68px;
      /* The tab bar's touch strip, and the one number everything that has to sit on top of
         it works from. Where a rule anchors something to the bottom of the screen the safe
         area is added on top of this value, never taken out of it — the strip stays 58px of
         thumb the whole way down, and the inset is fill, not space. */
      --nav-h: 58px;
    }

    html,
    body {
      height: 100%;
      font-family: var(--F-sans);
      background: var(--paper);
      color: var(--ink);
      -webkit-font-smoothing: antialiased;
      letter-spacing: 0;
    }

    #krug-root,
    #krug-root :where(:not(input):not(textarea):not(select):not([contenteditable="true"])) {
      -webkit-touch-callout: none;
      -webkit-user-select: none;
      user-select: none;
    }

    #krug-root :where(input, textarea, select, [contenteditable="true"]) {
      -webkit-user-select: text;
      user-select: text;
    }

    /* Images must not be draggable. */
    #krug-root img {
      -webkit-user-drag: none;
      user-drag: none;
      -webkit-user-select: none;
      user-select: none;
    }

    input,
    textarea,
    select {
      color: var(--ink) !important;
      background: var(--field) !important;
      color-scheme: inherit;
    }

    ::selection {
      background: var(--neon);
      color: #000;
    }

    button:focus-visible,
    a:focus-visible,
    input:focus-visible {
      outline: 1.5px solid var(--ink);
      outline-offset: 2px;
    }

    #app {
      min-height: 100vh;
      display: flex;
      flex-direction: column;
    }

    #app > :where(main, #home-page) {
      flex: 0 0 auto;
      width: 100%;
    }

    #app.map-mode {
      /* Fallback first, then the dynamic viewport: a browser without `dvh` keeps the old
         answer rather than dropping the declaration.

         This box is not merely tall, it is the thing the map and the zoom stack are measured
         from — `inset: 0` plus a height means the height wins over `bottom`, so the bottom
         edge of the shell is wherever the viewport unit says the screen ends. `100vh` is the
         height with Safari's toolbars retracted, which is not the height you have while its
         bottom toolbar is on screen: the map ran past the fold and behind the browser chrome,
         and anything anchored to the shell's bottom with it. `100dvh` follows the viewport
         the visitor is actually looking at, so the map ends where the screen does — above the
         tab bar, which is fixed to the same bottom edge. */
      height: 100vh;
      height: 100dvh;
      overflow: hidden;
      position: fixed;
      inset: 0;
    }

    /* TOP BAR */
    #topbar {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      z-index: 90;
      /* The other half of `viewport-fit=cover`. Asking for the whole screen is what lets the
         tab bar paint the home-indicator strip, and it is also what hands the top strip to
         the page: while Safari's own toolbars are on screen the inset is 0, and when they
         collapse on a scroll the island and the clock land in the top 44-59px of the layout
         viewport — over the logo, if the bar started at `top: 0` and stopped at 54px. The
         height grows by the inset and the inset comes back as padding, so the strip the
         visitor recognises is the same height it always was and the marks inside it stay
         under the glass rather than behind it. */
      height: calc(var(--top-h) + env(safe-area-inset-top, 0px));
      padding-top: env(safe-area-inset-top, 0px);
      background: rgba(0, 0, 0, .82);
      backdrop-filter: blur(14px);
      -webkit-backdrop-filter: blur(14px);
      border-bottom: 1px solid var(--line);
      display: flex;
      align-items: center;
    }

    .tb-logo {
      padding: 0 28px;
      display: flex;
      align-items: center;
      flex-shrink: 0;
      border-right: 1px solid var(--line);
      height: 100%;
      cursor: pointer;
      transition: background .2s;
    }

    .tb-logo:hover {
      background: var(--ink);
    }

    .tb-logo:hover .krug-circle-logo circle {
      fill: var(--on-ink);
    }

    .krug-logo-wrap {
      display: flex;
      align-items: center;
      gap: 11px;
    }

    .krug-circle-logo {
      flex-shrink: 0;
    }

    .krug-circle-logo circle {
      fill: var(--ink);
      transition: fill .2s;
    }

    .tb-center {
      flex: 1;
      padding: 0 18px;
      display: flex;
      align-items: center;
      gap: 8px;
    }

    .tb-nav-home {
      display: flex;
      gap: 6px;
      align-items: center;
      margin: 0 auto;
    }

    .tb-nav-home button {
      border: none;
      background: transparent;
      font-family: var(--F-sans);
      font-size: 10.5px;
      font-weight: 600;
      letter-spacing: .12em;
      text-transform: uppercase;
      cursor: pointer;
      padding: 8px 8px;
      color: var(--muted);
      transition: color .2s;
      white-space: nowrap;
      position: relative;
    }

    .tb-nav-home button:hover {
      color: var(--neon);
    }

    .tb-nav-home button.active {
      color: var(--neon);
    }

    .tb-nav-home button.active::after {
      content: "";
      position: absolute;
      left: 8px;
      right: 8px;
      bottom: -2px;
      height: 1px;
      background: var(--neon);
    }

    .tb-search {
      flex: 1;
      height: 40px;
      border: 1px solid var(--line);
      background: var(--field);
      border-radius: var(--r-pill);
      padding: 0 18px;
      font-family: var(--F-sans);
      font-size: 13px;
      color: var(--ink);
      outline: none;
      cursor: pointer;
      transition: border-color .2s;
    }

    .tb-search:hover {
      border-color: var(--line-strong);
    }

    .tb-search::placeholder {
      color: var(--muted);
    }

    .tb-right {
      padding: 0 18px;
      display: flex;
      align-items: center;
      gap: 10px;
      flex-shrink: 0;
      border-left: 1px solid var(--line);
      height: 100%;
    }

    .tb-btn {
      height: 38px;
      padding: 0 18px;
      border-radius: var(--r-pill);
      border: 1px solid var(--line-mid);
      background: var(--card);
      font-family: var(--F-sans);
      font-size: 10px;
      font-weight: 600;
      letter-spacing: .13em;
      text-transform: uppercase;
      cursor: pointer;
      white-space: nowrap;
      transition: background .2s, color .2s;
      color: var(--ink);
    }

    .tb-btn:hover {
      background: var(--neon);
      color: #000;
    }

    .tb-btn.solid {
      background: var(--neon);
      color: #000;
    }

    .tb-btn.solid:hover {
      background: var(--neon);
      color: #000;
    }

    /* HOME */
    #home-page {
      flex: 1;
    }

    .hero {
      position: relative;
      overflow: hidden;
      min-height: min(46vh, 520px);
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: flex-start;
      padding: 34px 0 8px;
      margin: 0;
      text-align: center;
    }

    /* HERO SLIDESHOW — rotating full-bleed background of editorial images */

    /* "sofia" wordmark sits ABOVE the slideshow but lets it show through via
       a transparent fill + thin outline, instead of a solid block colour. */
    .hero-word {
      position: relative;
      z-index: 2;
      font-family: var(--F-condensed);
      font-size: clamp(34px, 8.6vw, 140px);
      font-weight: 800;
      letter-spacing: -.02em;
      line-height: .95;
      text-transform: uppercase;
      color: #fff;
      mix-blend-mode: normal;
      margin: 0;
      text-shadow: 0 2px 18px rgba(0, 0, 0, .35), 0 1px 3px rgba(0, 0, 0, .25);
    }

    @supports not (-webkit-text-stroke: 1px #fff) {
      .hero-word {
        color: #fff;
        mix-blend-mode: normal;
      }
    }

    .krug-acro {
      display: flex;
      align-items: center;
      justify-content: space-between;
      width: 100%;
      padding: 0 2.5vw;
      gap: 14px;
      margin-top: 10px;
      font-family: var(--F-sans);
      font-size: clamp(10px, 1.6vw, 14px);
      font-weight: 500;
      letter-spacing: .18em;
      text-transform: uppercase;
      color: rgba(255, 255, 255, .62);
      text-shadow: 0 1px 14px rgba(0, 0, 0, .45);
      position: relative;
      z-index: 2;
    }

    .krug-acro b {
      font-weight: 800;
      color: #fff;
    }

    .krug-acro i {
      font-style: normal;
      color: rgba(255, 255, 255, .4);
      font-size: .8em;
    }

    @media (max-width: 600px) {
      .krug-acro {
        gap: 8px;
        letter-spacing: .2em;
        font-size: 9px;
      }
    }

    #hero-city {
      display: inline-block;
      min-width: 8ch;
      transition: opacity .35s;
      font-weight: 700;
    }

    /* The city in the hero eyebrow rotates on a timer. It used to carry its opacity
       through a `:style` binding, which the client never updates after hydration, so
       the name swapped with no fade at all; the transition above has been waiting for
       this class since it was written. */
    #hero-city.fading {
      opacity: 0;
    }

    .hero-eyebrow {
      position: relative;
      z-index: 2;
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 14px;
      margin-bottom: 40px;
      mix-blend-mode: normal;
      text-shadow: 0 1px 8px rgba(0, 0, 0, .35);
    }

    .hero .lbl {
      color: rgba(255, 255, 255, .82);
    }

    .lbl {
      font-family: var(--F-sans);
      font-size: 10px;
      font-weight: 600;
      letter-spacing: .32em;
      text-transform: uppercase;
      color: var(--muted);
    }

    .hero-circle {
      position: relative;
      z-index: 2;
      overflow: hidden;
      padding: 0;
      width: clamp(92px, 9vw, 124px);
      height: clamp(92px, 9vw, 124px);
      border-radius: 50%;
      background: rgba(255, 255, 255, .08);
      backdrop-filter: blur(6px);
      -webkit-backdrop-filter: blur(6px);
      border: 1px solid rgba(255, 255, 255, .85);
      margin: 56px auto 0;
      cursor: pointer;
      transition: transform .5s cubic-bezier(.22, 1, .36, 1), background .3s;
    }

    .hero-circle:hover {
      transform: scale(1.06);
      background: rgba(255, 255, 255, .16);
    }

    .hero-circle-label {
      position: absolute;
      inset: 0;
      z-index: 2;
      display: flex;
      align-items: center;
      justify-content: center;
      text-align: center;
      color: #fff;
      font-family: var(--F-sans);
      font-style: normal;
      font-weight: 600;
      font-size: 9px;
      letter-spacing: .2em;
      text-transform: uppercase;
    }

    /* pulsing ring on map locate button */
    #ctrl-locate::before {
      content: "";
      position: absolute;
      inset: -4px;
      border-radius: 22px;
      border: 1px solid var(--ink);
      opacity: 0;
      animation: pulse-ring 2.5s ease-out infinite;
    }

    #ctrl-locate {
      position: relative;
    }

    @keyframes pulse-ring {
      0% {
        transform: scale(.85);
        opacity: .2;
      }

      100% {
        transform: scale(1.5);
        opacity: 0;
      }
    }

    #mobile-nav button {
      position: relative;
    }

    /* Sofia message banner */

    @media (max-width:600px) {

      /* iOS Safari has to re-blur everything behind these on every single
         pan/zoom frame since they're fixed/absolute overlays sitting
         directly on top of the map — a well-known source of scroll/zoom
         jank. The backgrounds are already ~75-90% opaque, so dropping the
         blur here changes the look only slightly but removes the main
         performance cost. */
      #topbar {
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
        background: rgba(0, 0, 0, .94);
      }

      #detail {
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
        background: var(--card);
      }
    }

    .home-inner {
      max-width: 1320px;
      margin: 0 auto;
      padding: 0 24px 80px;
    }

    .sec-head {
      font-family: var(--F-condensed);
      font-size: clamp(30px, 5.8vw, 76px);
      font-weight: 600;
      letter-spacing: .02em;
      line-height: .96;
      text-transform: uppercase;
      text-align: center;
      margin-top: 44px;
      color: var(--ink);
    }

    .tabs {
      display: flex;
      justify-content: center;
      gap: 32px;
      margin: 40px 0 44px;
      overflow-x: auto;
      padding-bottom: 6px;
      scrollbar-width: none;
    }

    .tabs::-webkit-scrollbar {
      display: none;
    }

    .tabs button {
      border: none;
      background: none;
      font-family: var(--F-sans);
      font-size: 13px;
      font-weight: 400;
      letter-spacing: .01em;
      cursor: pointer;
      color: var(--muted);
      padding: 4px 0;
      border-bottom: 1px solid transparent;
      transition: color .2s, border-color .2s;
      white-space: nowrap;
    }

    .tabs button.active,
    .tabs button:hover {
      color: var(--neon);
      border-bottom-color: var(--neon);
    }

    .masonry {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 36px 32px;
      align-items: start;
    }

    .pin {
      position: relative;
      cursor: pointer;
      transition: transform .35s cubic-bezier(.22, 1, .36, 1), opacity .2s;
      border-radius: var(--r-card);
      overflow: hidden;
      background: var(--card);
      border: 1px solid var(--line);
      padding-bottom: 22px;
    }

    .pin:hover {
      opacity: .62;
    }

    /* Everything under the picture shares one inset: 20px from the card edge on a
       desktop, 16px from 600px down (the phone block at the end of this file). It
       used to be 2px, so a title in a 22px display face started three pixels from
       the card's own border and the copy read as pasted on top of the frame. The
       hero stays flush - it is the top edge of the card, not content inside it -
       which is why the inset lives on the text blocks and not as card padding. */
    .pin h3 {
      font-family: var(--F-display);
      font-size: 22px;
      font-weight: 500;
      line-height: 1.22;
      letter-spacing: -.02em;
      margin: 20px 20px 0;
    }

    .pin p {
      font-family: var(--F-sans);
      font-size: 10px;
      font-weight: 500;
      line-height: 1.65;
      margin: 10px 20px 0;
      color: var(--muted);
      letter-spacing: .12em;
      text-transform: uppercase;
    }

    /* Scoped to the card because .vibe-tags is drawn in three places and the other
       two sit inside their own containers. */
    .pin .vibe-tags {
      margin: 14px 20px 0;
    }

    .heart-btn {
      position: absolute;
      right: 12px;
      top: 12px;
      font-size: 15px;
      background: rgba(0, 0, 0, .55);
      backdrop-filter: blur(6px);
      -webkit-backdrop-filter: blur(6px);
      border: 1px solid rgba(255, 255, 255, .32);
      border-radius: 50%;
      width: 36px;
      height: 36px;
      display: flex;
      align-items: center;
      justify-content: center;
      cursor: pointer;
      transition: background .2s, color .2s;
      color: var(--ink);
      z-index: 2;
    }

    .heart-btn.saved {
      background: var(--neon);
      color: #000;
      border-color: var(--neon);
    }

    /* The card's own class - the week list uses .feed-save-count. */
    .save-count {
      font-family: var(--F-sans);
      font-size: 9px;
      font-weight: 600;
      color: var(--muted);
      margin: 10px 20px 0;
      letter-spacing: .12em;
      text-transform: uppercase;
    }

    .vibe-tags {
      display: flex;
      gap: 6px;
      flex-wrap: wrap;
      margin: 10px 2px 0;
    }

    .vibe-tag {
      font-family: var(--F-sans);
      font-size: 9px;
      font-weight: 600;
      letter-spacing: .06em;
      text-transform: uppercase;
      padding: 3px 9px;
      border-radius: var(--r-sm);
      background: transparent;
      color: var(--muted);
      border: 1px solid var(--line);
    }

    .star-rating {
      display: inline-flex;
      gap: 2px;
    }

    .star {
      font-size: 11px;
      color: var(--soft-2);
    }

    .star.lit {
      color: var(--ink);
    }

    .late-badge {
      display: inline-block;
      background: var(--neon);
      color: #000;
      font-family: var(--F-sans);
      font-size: 8px;
      font-weight: 600;
      letter-spacing: .1em;
      text-transform: uppercase;
      padding: 3px 9px;
      border-radius: var(--r-sm);
      margin-left: 6px;
      vertical-align: middle;
    }

    .event-distance-inline {
      white-space: nowrap;
      font-weight: 700;
    }

    .quote {
      margin: 120px 0 0;
      text-align: center;
      font-family: var(--F-serif);
      font-style: italic;
      font-size: clamp(22px, 3vw, 32px);
      font-weight: 300;
      border-top: 1px solid var(--line);
      padding-top: 48px;
      color: var(--ink);
      letter-spacing: 0;
    }

    /* Footer */
    .krug-footer {
      border-top: 1px solid var(--line);
      margin-top: auto;
      padding: 32px 24px;
      display: flex;
      flex-wrap: wrap;
      gap: 22px;
      align-items: center;
      justify-content: center;
      flex-shrink: 0;
      background: linear-gradient(to bottom, rgba(0, 0, 0, .65) 0%, rgba(0, 0, 0, .85) 50%, rgba(0, 0, 0, .95) 100%);
    }

    .footer-link {
      background: none;
      border: none;
      padding: 0;
      font-family: var(--F-sans);
      font-size: 11px;
      font-weight: 500;
      letter-spacing: .04em;
      color: #fff;
      cursor: pointer;
      transition: color .2s;
      text-decoration: none;
      display: inline-flex;
      align-items: center;
      gap: 6px;
      text-transform: uppercase;
    }

    .footer-link:hover {
      color: var(--ink);
    }

    .footer-copy {
      font-family: var(--F-sans);
      font-size: 10px;
      font-weight: 500;
      color: #fff;
      letter-spacing: .08em;
      text-transform: uppercase;
    }

    /* Sub-pages */
    .sub-page {
      display: none;
      max-width: 1000px;
      margin: 0 auto;
      padding: 60px 24px 80px;
    }

    .sub-page.active {
      display: block;
    }

    .sub-page h1 {
      font-family: var(--F-condensed);
      font-size: clamp(48px, 10.5vw, 140px);
      font-weight: 600;
      text-transform: uppercase;
      line-height: .96;
      letter-spacing: .015em;
      margin-bottom: 18px;
    }

    .sub-page-sub {
      font-family: var(--F-serif);
      font-style: italic;
      font-size: 17px;
      color: var(--muted);
      margin-bottom: 48px;
    }

    .list-empty-big {
      font-family: var(--F-serif);
      font-size: 24px;
      font-weight: 300;
      font-style: italic;
      color: var(--muted);
      text-transform: lowercase;
    }

    /* Tonight / Past rows */
    .tonight-row {
      display: grid;
      grid-template-columns: 110px 1fr;
      border-bottom: 1px solid var(--line);
      cursor: pointer;
      transition: background .15s;
    }

    .tonight-row:hover {
      background: var(--soft);
    }

    .tonight-time-col {
      padding: 24px 0;
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 5px;
      border-right: 1px solid var(--line);
    }

    .tonight-time {
      font-family: var(--F-sans);
      font-size: 15px;
      font-weight: 600;
      letter-spacing: .01em;
      text-align: center;
    }

    .tonight-day-label {
      display: block;
      font-size: 9px;
      font-weight: 700;
      letter-spacing: .1em;
      text-transform: uppercase;
      color: var(--muted);
      margin-bottom: 2px;
    }

    .tonight-info {
      padding: 22px 24px;
    }

    .tonight-title {
      font-family: var(--F-display);
      font-size: 20px;
      font-weight: 500;
      line-height: 1.22;
      letter-spacing: -.015em;
      margin-bottom: 6px;
    }

    .tonight-meta {
      font-family: var(--F-sans);
      font-size: 10px;
      color: var(--muted);
      letter-spacing: .12em;
      text-transform: uppercase;
    }

    .cat-pill {
      display: inline-block;
      font-family: var(--F-sans);
      font-size: 8px;
      font-weight: 600;
      border: 1px solid var(--ink);
      padding: 4px 11px;
      border-radius: var(--r-sm);
      letter-spacing: .16em;
      text-transform: uppercase;
      margin-top: 10px;
    }

    .past-row {
      display: grid;
      grid-template-columns: 110px 1fr;
      border-bottom: 1px solid var(--line);
      opacity: .55;
    }

    .past-date-col {
      padding: 22px 0;
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 5px;
      border-right: 1px solid var(--line);
    }

    .past-date-txt {
      font-family: var(--F-sans);
      font-size: 9px;
      font-weight: 600;
      color: var(--muted);
      text-align: center;
      line-height: 1.4;
      letter-spacing: .08em;
      text-transform: uppercase;
    }

    .past-info {
      padding: 18px 24px;
    }

    .past-title {
      font-family: var(--F-display);
      font-size: 17px;
      font-weight: 500;
      line-height: 1.3;
      color: var(--muted);
      letter-spacing: -.01em;
    }

    .past-meta {
      font-family: var(--F-sans);
      font-size: 10px;
      color: var(--muted);
      letter-spacing: .12em;
      text-transform: uppercase;
      margin-top: 5px;
    }

    .saved-masonry {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 36px 32px;
      align-items: start;
    }

    .saved-empty {
      font-family: var(--F-serif);
      font-style: italic;
      font-size: 20px;
      font-weight: 300;
      color: var(--muted);
      text-align: center;
      padding: 100px 0;
      line-height: 2;
      text-transform: lowercase;
    }

    /* Rate modal */
    #rate-modal {
      display: none;
      position: fixed;
      inset: 0;
      z-index: 400;
      background: rgba(10, 10, 10, .55);
      align-items: center;
      justify-content: center;
    }

    #rate-modal.open {
      display: flex;
    }

    .rate-box {
      background: var(--card);
      border: 1px solid var(--ink);
      border-radius: var(--r-sm);
      padding: 40px 36px;
      max-width: 380px;
      width: 90%;
      text-align: center;
    }

    .rate-box h3 {
      font-family: var(--F-display);
      font-size: 24px;
      font-weight: 400;
      margin-bottom: 8px;
      text-transform: lowercase;
      letter-spacing: -.02em;
    }

    .rate-box p {
      font-family: var(--F-sans);
      font-size: 12px;
      color: var(--muted);
      margin-bottom: 24px;
    }

    .rate-stars {
      display: flex;
      justify-content: center;
      gap: 12px;
      margin-bottom: 24px;
    }

    .rate-star {
      font-size: 34px;
      cursor: pointer;
      color: var(--soft-2);
      transition: color .15s, transform .15s;
    }

    .rate-star:hover,
    .rate-star.lit {
      color: var(--ink);
      transform: scale(1.1);
    }

    .rate-submit {
      width: 100%;
      background: var(--neon);
      color: #000;
      border: 1px solid var(--ink);
      border-radius: var(--r-sm);
      padding: 15px;
      font-family: var(--F-sans);
      font-size: 10px;
      font-weight: 600;
      letter-spacing: .16em;
      text-transform: uppercase;
      cursor: pointer;
      transition: background .2s, color .2s;
    }

    .rate-submit:hover {
      background: var(--neon);
      color: #000;
    }

    .rate-skip {
      background: none;
      border: none;
      color: var(--muted);
      font-family: var(--F-sans);
      font-size: 11px;
      cursor: pointer;
      margin-top: 14px;
      text-decoration: underline;
      text-underline-offset: 3px;
    }

    /* MAP MODE */
    #map-shell {
      display: none;
      flex: 1;
      overflow: hidden;
      position: relative;
    }

    #app.map-mode #map-shell {
      display: flex;
    }

    #app.map-mode #home-page {
      display: none;
    }

    #app.map-mode #global-footer {
      display: none;
    }

    #panel {
      width: var(--panel-w);
      flex-shrink: 0;
      background: var(--card);
      border-right: 1px solid var(--line);
      display: flex;
      flex-direction: column;
      overflow: hidden;
      z-index: 10;
      transition: transform .35s cubic-bezier(.22, 1, .36, 1);
    }

    #panel.hidden {
      transform: translateX(-100%);
    }

    #panel-toggle {
      position: absolute;
      left: calc(var(--panel-w) - 1px);
      top: 50%;
      transform: translateY(-50%);
      z-index: 20;
      background: var(--card);
      border: 1px solid var(--line);
      border-left: none;
      border-radius: var(--r-sm);
      width: 22px;
      height: 60px;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 11px;
      color: var(--muted);
      transition: left .35s cubic-bezier(.22, 1, .36, 1), color .2s;
    }

    #panel-toggle:hover {
      color: var(--ink);
    }

    #panel.hidden+#panel-toggle {
      left: 0;
    }

    .panel-view {
      display: none;
      flex-direction: column;
      flex: 1;
      overflow: hidden;
    }

    .panel-view.active {
      display: flex;
    }

    .panel-filters {
      padding: 14px 20px 10px;
      border-bottom: 1px solid var(--line);
      display: flex;
      gap: 6px;
      overflow-x: auto;
      scrollbar-width: none;
      flex-shrink: 0;
    }

    .panel-filters::-webkit-scrollbar {
      display: none;
    }

    .chip {
      border: 1px solid var(--line-mid);
      background: transparent;
      color: var(--muted);
      border-radius: var(--r-sm);
      padding: 6px 12px;
      font-family: var(--F-sans);
      font-size: 8px;
      font-weight: 600;
      letter-spacing: .14em;
      cursor: pointer;
      text-transform: uppercase;
      transition: background .15s, color .15s, border-color .15s;
      white-space: nowrap;
      flex-shrink: 0;
    }

    .chip.on,
    .chip:hover {
      background: var(--neon);
      color: var(--on-ink);
      border-color: var(--neon);
    }

    /* Filters (city/category/vibe) are desktop-hidden by default — wherever the panel
       is a sheet they live inside the collapsible filter stack instead, keeping the
       sheet clean and focused on the event list. 901px is the width at which the panel
       stops being a sheet, so it is the width at which they come back. */
    @media (min-width:901px) {

      #panel .panel-filters {
        display: none !important;
      }
    }

    .vchip {
      border: 1px solid var(--line-mid);
      background: transparent;
      color: var(--muted);
      border-radius: var(--r-sm);
      padding: 5px 11px;
      font-family: var(--F-sans);
      font-size: 8px;
      font-weight: 600;
      letter-spacing: .04em;
      cursor: pointer;
      white-space: nowrap;
      flex-shrink: 0;
      transition: background .15s, color .15s, border-color .15s;
    }

    .vchip.on {
      background: var(--neon);
      color: var(--on-ink);
      border-color: var(--neon);
    }

    .vchip:hover:not(.on) {
      border-color: var(--line-strong);
      color: var(--ink);
    }

    .map-filter-stack {
      border-bottom: 1px solid var(--line);
      padding: 14px 20px 12px;
      display: flex;
      flex-direction: column;
      gap: 9px;
      flex-shrink: 0;
    }

    .map-filter-toolbar {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 12px;
      min-height: 22px;
    }

    .map-filter-title,
    .map-filter-clear {
      display: inline-flex;
      align-items: center;
      gap: 7px;
      font-family: var(--F-sans);
      font-size: 8px;
      font-weight: 700;
      letter-spacing: .18em;
      text-transform: uppercase;
    }

    .map-filter-title {
      color: var(--ink);
    }

    .map-filter-clear {
      border: 1px solid var(--line-mid);
      background: transparent;
      color: var(--muted);
      border-radius: var(--r-sm);
      height: 26px;
      padding: 0 9px;
      cursor: pointer;
      transition: background .15s, color .15s, border-color .15s;
      flex-shrink: 0;
      white-space: nowrap;
    }

    .map-filter-clear:hover {
      background: var(--neon);
      border-color: var(--neon);
      color: var(--on-ink);
    }

    /* Filter dropdowns. The trigger is a chip like every other pill control, and the
       panel it opens is the list the add-event vibes combobox already uses, so a
       filter menu looks and behaves like the menus the rest of the site has. */
    .map-filter-bar {
      display: flex;
      flex-wrap: wrap;
      align-items: flex-start;
      gap: 7px;
      min-width: 0;
    }

    .map-filter-dd {
      position: relative;
      flex: 1 1 auto;
      min-width: 148px;
    }

    .map-filter-dd-trigger {
      display: flex;
      align-items: center;
      gap: 6px;
      width: 100%;
      min-height: 28px;
      border: 1px solid var(--line-mid);
      background: transparent;
      border-radius: var(--r-pill);
      padding: 5px 10px;
      cursor: pointer;
      font-family: var(--F-sans);
      font-size: 8px;
      font-weight: 600;
      letter-spacing: .14em;
      text-transform: uppercase;
      color: var(--muted);
      transition: background .15s, color .15s, border-color .15s;
    }

    .map-filter-dd-trigger:hover,
    .map-filter-dd-trigger.on {
      background: var(--neon);
      border-color: var(--neon);
      color: var(--on-ink);
    }

    .map-filter-dd-trigger:focus-visible {
      outline: 1px solid var(--neon);
      outline-offset: 2px;
    }

    .map-filter-dd-label {
      flex: 0 0 auto;
      color: var(--muted);
    }

    .map-filter-dd-value {
      flex: 1 1 auto;
      min-width: 0;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      color: var(--ink-dim);
    }

    .map-filter-dd-trigger:hover .map-filter-dd-label,
    .map-filter-dd-trigger.on .map-filter-dd-label {
      color: var(--on-ink-muted);
    }

    .map-filter-dd-trigger:hover .map-filter-dd-value,
    .map-filter-dd-trigger.on .map-filter-dd-value {
      color: var(--on-ink);
    }

    .map-filter-dd-caret {
      flex: 0 0 auto;
      transition: transform .18s ease;
    }

    .map-filter-dd.open .map-filter-dd-caret {
      transform: rotate(180deg);
    }

    /* The panel is exactly as wide as the control that opened it. The map panel clips
       what crosses its edge, so a menu allowed to grow past its trigger would arrive
       with a border missing. */
    .map-filter-options {
      position: absolute;
      top: calc(100% + 6px);
      left: 0;
      right: 0;
      z-index: 30;
      display: grid;
      gap: 2px;
      max-height: min(228px, 42vh);
      overflow-y: auto;
      overscroll-behavior: contain;
      padding: 4px;
      border: 1px solid var(--line-mid);
      border-radius: var(--r-sm);
      background: var(--card);
      box-shadow: 0 18px 44px rgba(0, 0, 0, .55);
    }

    .map-filter-options .chip,
    .map-filter-options .vchip {
      display: flex;
      align-items: center;
      gap: 8px;
      width: 100%;
      border: 0;
      border-radius: calc(var(--r-sm) - 4px);
      background: transparent;
      color: var(--muted);
      padding: 7px 10px;
      font-size: 10px;
      letter-spacing: .04em;
      text-align: left;
      cursor: pointer;
      transition: background .15s, color .15s;
    }

    /* Selected before hovered, on purpose: pointing at a row that is already ticked
       still has to show the wash, or the menu reads as if that row cannot be
       unticked. */
    .map-filter-options .chip.on,
    .map-filter-options .vchip.on {
      background: transparent;
      border-color: transparent;
      color: var(--neon);
    }

    .map-filter-options .chip:hover,
    .map-filter-options .vchip:hover {
      background: rgba(255, 255, 255, .07);
      border-color: transparent;
      color: var(--neon);
    }

    .map-filter-options .chip:focus-visible,
    .map-filter-options .vchip:focus-visible {
      outline: 1px solid var(--neon);
      outline-offset: -1px;
    }

    /* The tick is drawn, never written: an option's text stays exactly the name. */
    .map-filter-options .chip::before,
    .map-filter-options .vchip::before {
      content: "";
      flex: 0 0 12px;
      width: 12px;
      font-size: 10px;
      line-height: 1;
    }

    .map-filter-options .chip.on::before,
    .map-filter-options .vchip.on::before {
      content: "✓";
    }

    .map-filter-options .chip-dot {
      margin-right: 0;
      vertical-align: middle;
    }

    .map-filter-option-label {
      min-width: 0;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    .panel-count {
      padding: 14px 20px 12px;
      font-family: var(--F-sans);
      font-size: 9px;
      font-weight: 600;
      letter-spacing: .24em;
      text-transform: uppercase;
      color: var(--ink);
      border-bottom: 1px solid var(--line);
      flex-shrink: 0;
    }

    #map-events-list {
      overflow-y: auto;
      flex: 1;
    }

    .event-row {
      display: flex;
      gap: 14px;
      align-items: flex-start;
      padding: 16px;
      border-bottom: 1px solid var(--line);
      cursor: pointer;
      transition: background .15s;
    }

    .event-row:hover {
      background: var(--soft);
    }

    .event-row.selected {
      background: var(--ink);
    }

    .event-row.selected .event-row-title {
      color: var(--on-ink);
    }

    .event-row.selected .event-row-meta,
    .event-row.selected .event-row-badge,
    .event-row.selected .src-chip {
      color: var(--on-ink-muted);
      border-color: var(--on-ink-muted);
    }

    .event-row-info {
      flex: 1;
      min-width: 0;
    }

    .event-row-title {
      font-family: var(--F-display);
      font-size: 14px;
      font-weight: 500;
      line-height: 1.3;
      letter-spacing: -.01em;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    .event-row-meta {
      font-family: var(--F-sans);
      font-size: 10px;
      color: var(--muted);
      margin-top: 4px;
      line-height: 1.5;
      letter-spacing: .04em;
    }

    .event-row-badge {
      display: inline-block;
      font-family: var(--F-sans);
      font-size: 7.5px;
      font-weight: 600;
      letter-spacing: .14em;
      text-transform: uppercase;
      border: 1px solid var(--line);
      border-radius: var(--r-sm);
      padding: 3px 8px;
      color: var(--muted);
      margin-top: 6px;
    }

    .event-row-tags {
      display: flex;
      align-items: center;
      gap: 5px;
      flex-wrap: wrap;
      margin-top: 6px;
    }

    .event-row-tags .event-row-badge,
    .event-row-tags .src-chip {
      margin-top: 0;
    }

    .add-form {
      padding: 18px 18px 48px;
    }

    .fg {
      margin-bottom: 18px;
    }

    .fg label {
      display: block;
      font-family: var(--F-sans);
      font-size: 8px;
      font-weight: 600;
      letter-spacing: .2em;
      text-transform: uppercase;
      color: var(--ink);
      margin-bottom: 8px;
    }

    .fg input,
    .fg select,
    .fg textarea {
      width: 100%;
      border: 1px solid var(--line);
      border-radius: var(--r-sm);
      padding: 11px 14px;
      font-family: var(--F-sans);
      font-size: 13px;
      color: var(--ink);
      background: var(--field);
      transition: border-color .2s;
      outline: none;
    }

    .fg input:focus,
    .fg select:focus,
    .fg textarea:focus {
      border-color: var(--neon);
    }

    .fg textarea {
      resize: vertical;
      min-height: 84px;
    }

    .fg-row {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 14px;
      margin-bottom: 18px;
    }

    .add-submit {
      width: 100%;
      background: var(--neon);
      color: #000;
      border: 1px solid var(--ink);
      border-radius: var(--r-sm);
      padding: 15px;
      font-family: var(--F-sans);
      font-size: 10px;
      font-weight: 600;
      letter-spacing: .16em;
      text-transform: uppercase;
      cursor: pointer;
      transition: background .2s, color .2s;
      margin-top: 6px;
    }

    .add-submit:hover {
      background: var(--neon);
      color: #000;
    }

    .add-submit:disabled {
      opacity: .4;
      cursor: not-allowed;
    }

    .add-success {
      background: var(--soft);
      border: 1px solid var(--ink);
      border-radius: var(--r-sm);
      padding: 13px 16px;
      font-family: var(--F-sans);
      font-size: 11px;
      font-weight: 600;
      color: var(--ink);
      margin-bottom: 16px;
      display: none;
    }

    /* ── EVENT LOCATION PICKER ───────────────────────── */

    /* The form's own map: the map page's dark treatment at the size of a
       field, because an event without a placed pin has no place on /map. */
    .event-map {
      position: relative;
      height: 260px;
      border: 1px solid var(--line);
      border-radius: var(--r-sm);
      background: #050506;
      overflow: hidden;
      transition: border-color .2s;
    }

    .event-map:focus-within,
    .event-map.has-pin {
      border-color: var(--line-strong);
    }

    /* MapLibre's stylesheet lands in <head> after this file and its
       `.maplibregl-map { position: relative }` would otherwise win, collapsing
       the container to zero height: the map then sizes itself to the canvas
       default and paints outside the field. Two classes to outrank it. */
    .event-map .event-map-canvas,
    .event-map-canvas.maplibregl-map {
      position: absolute;
      inset: 0;
      width: 100%;
      height: 100%;
      outline: none;
    }

    .event-map .maplibregl-map {
      background: #050506;
      font-family: var(--F-sans);
    }

    .event-map .maplibregl-canvas {
      filter: contrast(1.03) saturate(.88);
      outline: none;
    }

    .event-map-tools {
      position: absolute;
      z-index: 20;
      top: 10px;
      right: 10px;
      display: flex;
      flex-direction: column;
      gap: 6px;
    }

    .event-map-btn {
      width: 34px;
      height: 34px;
      display: flex;
      align-items: center;
      justify-content: center;
      background: var(--card);
      border: 1px solid var(--line-mid);
      border-radius: 10px;
      color: var(--ink);
      cursor: pointer;
      transition: background .18s, color .18s;
    }

    .event-map-btn:hover {
      background: var(--neon);
      color: var(--on-ink);
    }

    .event-map-btn:disabled {
      opacity: .4;
      cursor: not-allowed;
    }

    .event-map-hint,
    .event-map-flag {
      position: absolute;
      z-index: 20;
      left: 50%;
      top: 12px;
      transform: translateX(-50%);
      max-width: calc(100% - 76px);
      padding: 6px 11px;
      border: 1px solid var(--line-mid);
      border-radius: var(--r-pill);
      background: var(--card);
      font-family: var(--F-sans);
      font-size: 9px;
      font-weight: 600;
      letter-spacing: .12em;
      text-transform: uppercase;
      color: var(--ink-dim);
      text-align: center;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      pointer-events: none;
    }

    .event-map-flag {
      color: var(--ink);
    }

    .event-map-fallback {
      position: absolute;
      inset: 0;
      z-index: 25;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 10px;
      padding: 0 22px;
      background: var(--soft);
      font-family: var(--F-sans);
      font-size: 11px;
      font-weight: 600;
      color: var(--ink-dim);
      text-align: center;
    }

    /* The map is a required field, so a failed load must not be a dead end: the
       sentence comes with the one action that can still fix it. */
    .event-map-retry {
      border: 1px solid var(--line-mid);
      border-radius: var(--r-pill);
      padding: 7px 16px;
      background: var(--card);
      color: var(--ink);
      font-family: var(--F-sans);
      font-size: 9px;
      font-weight: 700;
      letter-spacing: 0.14em;
      text-transform: uppercase;
      cursor: pointer;
      transition:
        background 0.15s ease,
        color 0.15s ease;
    }

    .event-map-retry:hover:not(:disabled) {
      background: var(--neon);
      color: var(--on-ink);
    }

    .event-map-retry:disabled {
      opacity: 0.4;
      cursor: default;
    }

    .event-map-coords {
      display: flex;
      align-items: baseline;
      gap: 8px;
      margin-top: 8px;
    }

    .event-map-coords-label {
      font-family: var(--F-sans);
      font-size: 8px;
      font-weight: 600;
      letter-spacing: .2em;
      text-transform: uppercase;
      color: var(--muted);
    }

    .event-map-coords-value {
      font-family: var(--F-sans);
      font-size: 10px;
      font-weight: 600;
      letter-spacing: .08em;
      color: var(--ink-dim);
    }

    /* Where a pair copied out of Google Maps or OpenStreetMap goes. It is a field of
       the form and not chrome of the map: it sits under the map with the input styling
       the form already gives its fields, so it inherits the site's font, the focus ring
       and the 16px a phone needs to keep the page from zooming. The readout under it
       stays the last word, because the readout is what the row will hold. */
    .event-map-paste {
      margin-top: 10px;
    }

    .event-map-paste-label {
      display: block;
      margin-bottom: 6px;
      font-family: var(--F-sans);
      font-size: 8px;
      font-weight: 600;
      letter-spacing: .2em;
      text-transform: uppercase;
      color: var(--muted);
    }

    .event-map-paste-row {
      display: flex;
      align-items: stretch;
      gap: 8px;
    }

    .event-map-paste .event-map-paste-input {
      flex: 1 1 auto;
      min-width: 0;
    }

    .event-map-paste-btn {
      flex: 0 0 auto;
      border: 1px solid var(--line-mid);
      border-radius: var(--r-pill);
      padding: 0 16px;
      background: var(--card);
      color: var(--ink);
      font-family: var(--F-sans);
      font-size: 9px;
      font-weight: 700;
      letter-spacing: .14em;
      text-transform: uppercase;
      white-space: nowrap;
      cursor: pointer;
      transition:
        background 0.15s ease,
        color 0.15s ease;
    }

    .event-map-paste-btn:hover:not(:disabled) {
      background: var(--neon);
      color: var(--on-ink);
    }

    .event-map-paste-btn:disabled {
      opacity: 0.4;
      cursor: default;
    }

    .event-map-paste-hint,
    .event-map-paste-note,
    .event-map-paste-error {
      margin: 7px 0 0;
      font-family: var(--F-sans);
      font-size: 10px;
      line-height: 1.45;
      color: var(--muted);
    }

    /* A refusal is the one line under the box that has to be read, so it is the
       brightest of the three. No red: the site has no red. */
    .event-map-paste-error {
      color: var(--ink);
    }

    .event-map-paste-note {
      color: var(--ink-dim);
    }

    /* The pin reads as the selected marker on the map page, lifted off the
       surface and draggable. */
    .krug-pin {
      position: relative;
      width: 18px;
      height: 18px;
      border-radius: 50%;
      background: var(--neon);
      box-shadow: 0 0 0 3px rgba(255, 255, 255, .26), 0 6px 14px rgba(0, 0, 0, .65);
      cursor: grab;
    }

    .krug-pin::after {
      content: '';
      position: absolute;
      inset: 5px;
      border-radius: 50%;
      background: var(--on-ink);
    }

    .krug-pin:active {
      cursor: grabbing;
    }

    .event-map .maplibregl-ctrl-attrib {
      font-size: 9px;
    }

    @media (max-width: 600px) {
      .event-map {
        height: 220px;
      }

      .event-map-hint,
      .event-map-flag {
        font-size: 8px;
        letter-spacing: .1em;
      }
    }

    /* ── ORGANISE / SECRET (added) ───────────────────── */

    .org-intro {
      font-family: var(--F-serif);
      font-style: italic;
      font-weight: 300;
      font-size: 22px;
      line-height: 1.5;
      max-width: 640px;
      margin-bottom: 44px;
      color: var(--ink);
    }

    .org-pillars {
      max-width: 640px;
      margin-bottom: 40px;
    }

    .org-pillar {
      padding: 22px 0;
      border-top: 1px solid var(--line);
    }

    .org-pillar:last-child {
      border-bottom: 1px solid var(--line);
    }

    .org-pillar-label {
      font-family: var(--F-sans);
      font-size: 10px;
      font-weight: 600;
      letter-spacing: .16em;
      text-transform: uppercase;
      color: var(--ink);
      margin-bottom: 8px;
    }

    .org-pillar-text {
      font-family: var(--F-sans);
      font-size: 14px;
      line-height: 1.7;
      color: color-mix(in srgb, var(--ink) 74%, var(--paper));
    }

    .org-closing {
      font-family: var(--F-serif);
      font-style: italic;
      font-size: 16px;
      color: var(--ink);
      max-width: 640px;
      margin-bottom: 44px;
    }

    .org-contact-row {
      display: flex;
      justify-content: space-between;
      align-items: baseline;
      padding: 16px 0;
      border-top: 1px solid var(--line);
      max-width: 640px;
    }

    .org-contact-row:last-of-type {
      border-bottom: 1px solid var(--line);
    }

    .org-contact-label {
      font-family: var(--F-sans);
      font-size: 10px;
      letter-spacing: .14em;
      text-transform: uppercase;
      color: var(--muted);
    }

    .org-contact-value {
      font-family: var(--F-sans);
      font-size: 13px;
      color: var(--ink);
      transition: color .2s;
    }

    .org-contact-value:hover {
      color: var(--muted);
    }

    .about-wrap {
      max-width: 680px;
      margin: 0 auto;
    }

    .about-section {
      margin-bottom: 64px;
    }

    .about-lead {
      font-family: var(--F-condensed);
      font-size: clamp(26px, 4.6vw, 48px);
      font-weight: 600;
      text-transform: uppercase;
      line-height: 1.04;
      letter-spacing: .015em;
      margin-bottom: 14px;
    }

    .about-lead-small {
      font-size: clamp(20px, 3.2vw, 32px);
    }

    .about-head {
      font-family: var(--F-condensed);
      font-size: clamp(22px, 3.6vw, 36px);
      font-weight: 600;
      text-transform: uppercase;
      line-height: 1.06;
      letter-spacing: .015em;
      margin-bottom: 22px;
    }

    .about-body {
      font-family: var(--F-sans);
      font-size: 15px;
      line-height: 1.7;
      color: color-mix(in srgb, var(--ink) 78%, var(--paper));
      margin-bottom: 12px;
      max-width: 600px;
    }

    .about-punch {
      font-family: var(--F-serif);
      font-style: italic;
      font-weight: 300;
      font-size: 20px;
      line-height: 1.45;
      color: var(--ink);
      margin: 18px 0;
      max-width: 600px;
    }

    .about-quote {
      font-family: var(--F-serif);
      font-style: italic;
      font-weight: 300;
      font-size: clamp(24px, 4vw, 40px);
      line-height: 1.25;
      color: var(--ink);
      margin: 18px 0 22px;
    }

    .about-quote-inline {
      font-size: 22px;
      margin: 10px 0;
    }

    .about-step {
      padding: 22px 0;
      border-top: 1px solid var(--line);
      max-width: 640px;
    }

    .about-step:last-child {
      border-bottom: 1px solid var(--line);
    }

    .about-step-label {
      font-family: var(--F-sans);
      font-size: 10px;
      font-weight: 600;
      letter-spacing: .16em;
      text-transform: uppercase;
      color: var(--ink);
      margin-bottom: 10px;
    }

    .about-checklist {
      list-style: none;
      padding: 0;
      margin: 14px 0 14px;
      max-width: 640px;
    }

    .about-checklist li {
      font-family: var(--F-sans);
      font-size: 13px;
      font-weight: 600;
      letter-spacing: .08em;
      text-transform: uppercase;
      color: var(--ink);
      padding: 10px 0 10px 22px;
      border-top: 1px solid var(--line);
      position: relative;
    }

    .about-checklist li::before {
      content: '';
      position: absolute;
      left: 2px;
      top: 50%;
      width: 7px;
      height: 7px;
      border: 1px solid var(--line-strong);
      border-radius: 50%;
      transform: translateY(-50%);
    }

    .about-checklist li:last-child {
      border-bottom: 1px solid var(--line);
    }

    @media (max-width: 600px) {
      .about-section {
        margin-bottom: 48px;
      }
    }

    .auth-page-form {
      max-width: 380px;
    }

    .auth-note {
      font-family: var(--F-sans);
      font-size: 11.5px;
      color: var(--muted);
      margin-top: 16px;
      line-height: 1.6;
    }

    @media (max-width: 600px) {
      .org-intro {
        font-size: 19px;
      }

      .org-contact-row {
        flex-direction: column;
        align-items: flex-start;
        gap: 4px;
      }
    }

    .ai-btn {
      padding: 9px 14px;
      background: var(--neon);
      color: #000;
      border: 1px solid var(--ink);
      border-radius: var(--r-sm);
      font-family: var(--F-sans);
      font-size: 8px;
      font-weight: 600;
      letter-spacing: .14em;
      text-transform: uppercase;
      cursor: pointer;
      white-space: nowrap;
      transition: background .2s, color .2s;
    }

    .ai-btn:hover {
      background: var(--neon);
      color: #000;
    }

    /* ── Vibes multi combobox (event add/edit) ── */
    .vibe-combobox {
      display: grid;
      gap: 8px;
    }

    .vibe-selected-chips {
      display: flex;
      flex-wrap: wrap;
      gap: 7px;
    }

    .vibe-chip {
      display: inline-flex;
      align-items: center;
      gap: 7px;
      max-width: 100%;
      border: 1px solid var(--neon);
      background: var(--neon);
      color: #000;
      border-radius: var(--r-sm);
      padding: 6px 8px 6px 12px;
      font-family: var(--F-sans);
      font-size: 9px;
      font-weight: 600;
      letter-spacing: .04em;
      text-transform: uppercase;
    }

    .vibe-chip > span:first-child {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    .vibe-chip-remove {
      border: 0;
      background: transparent;
      color: inherit;
      font-family: var(--F-sans);
      font-size: 13px;
      line-height: 1;
      padding: 0 2px;
      cursor: pointer;
    }

    .vibe-combobox-control {
      display: grid;
      grid-template-columns: minmax(0, 1fr) auto;
      gap: 8px;
      align-items: stretch;
    }

    .vibe-combobox-input {
      min-width: 0;
    }

    .vibe-combobox-input:disabled {
      opacity: .45;
      cursor: not-allowed;
    }

    .vibe-combobox-caret {
      border: 1px solid var(--line-mid);
      border-radius: var(--r-sm);
      background: transparent;
      color: var(--muted);
      padding: 0 12px;
      font-size: 9px;
      cursor: pointer;
      transition: color .15s, border-color .15s;
    }

    .vibe-combobox-caret:hover {
      color: var(--neon);
      border-color: var(--neon);
    }

    .vibe-combobox-list {
      list-style: none;
      margin: 0;
      padding: 4px;
      display: grid;
      gap: 2px;
      max-height: 210px;
      overflow-y: auto;
      border: 1px solid var(--line-mid);
      border-radius: var(--r-sm);
      background: rgba(255, 255, 255, .04);
    }

    .vibe-combobox-option {
      display: flex;
      align-items: center;
      gap: 8px;
      padding: 7px 10px;
      border-radius: calc(var(--r-sm) - 4px);
      cursor: pointer;
      user-select: none;
      font-family: var(--F-sans);
      font-size: 10px;
      font-weight: 600;
      letter-spacing: .04em;
      text-transform: uppercase;
      color: var(--muted);
      transition: background .15s, color .15s;
    }

    .vibe-combobox-option:hover {
      color: var(--neon);
      background: rgba(255, 255, 255, .07);
    }

    .vibe-combobox-option:focus-visible {
      outline: 1px solid var(--neon);
      outline-offset: -1px;
    }

    .vibe-combobox-option.sel {
      color: var(--neon);
    }

    .vibe-option-mark {
      width: 14px;
      flex: 0 0 14px;
      text-align: center;
    }

    .vibe-option-label {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    .vibe-combobox-empty {
      padding: 9px 10px;
      font-family: var(--F-sans);
      font-size: 10px;
      letter-spacing: .04em;
      color: var(--muted);
    }

    .vibe-combobox-foot {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 8px;
    }

    #map-area {
      flex: 1;
      position: relative;
      overflow: hidden;
    }

    #map-el {
      position: absolute;
      inset: 0;
    }

    .map-ctrl {
      position: absolute;
      z-index: 20;
      background: var(--card);
      border: 1px solid var(--line);
      border-radius: var(--r-sm);
      box-shadow: none;
      overflow: hidden;
    }

    #ctrl-zoom {
      bottom: 110px;
      right: 18px;
      display: flex;
      flex-direction: column;
    }

    #ctrl-locate {
      top: 16px;
      left: 50%;
      right: auto;
      bottom: auto;
      transform: translateX(-50%);
      width: auto;
      height: 42px;
      border-radius: 22px;
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 7px;
      padding: 0 16px 0 14px;
      cursor: pointer;
      font-size: 15px;
      border: 1px solid var(--line-mid);
      background: var(--card);
      box-shadow: none;
      transition: background .2s, color .2s;
    }

    #ctrl-locate:hover {
      background: var(--neon);
      color: #000;
    }

    #ctrl-locate-icon {
      font-size: 14px;
      line-height: 1;
    }

    #ctrl-locate-label {
      display: none !important;
    }

    #ctrl-locate {
      width: 42px !important;
      padding: 0 !important;
      gap: 0 !important;
    }

    #ctrl-locate-icon {
      font-size: 18px !important;
    }

    .zoom-btn {
      width: 40px;
      height: 40px;
      border: none;
      background: var(--card);
      cursor: pointer;
      font-size: 18px;
      font-weight: 300;
      color: var(--ink);
      transition: background .15s;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .zoom-btn:hover {
      background: var(--soft);
    }

    .zoom-btn:first-child {
      border-bottom: 1px solid var(--line);
    }

    #detail {
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      background: color-mix(in srgb, var(--card) 74%, transparent);
      backdrop-filter: blur(22px) saturate(1.15);
      -webkit-backdrop-filter: blur(22px) saturate(1.15);
      border-top: 1px solid var(--line-mid);
      border-radius: var(--r-card) var(--r-card) 0 0;
      box-shadow: 0 -8px 40px rgba(0, 0, 0, .08);
      transform: translateY(100%);
      transition: transform .35s cubic-bezier(.22, 1, .36, 1);
      z-index: 30;
      max-height: 78%;
      display: flex;
      flex-direction: column;
    }

    #detail.show {
      transform: translateY(0);
    }

    /* The docked card, which is what the event is beside the list on a desktop. It
       starts where the list stops being a sheet: 901px, not 700px. Between the two the
       card and the list were both floating over the map at once, the card overlapping
       the list by fifty pixels at tablet widths. */
    @media (min-width:901px) {
      #detail {
        top: 18px;
        bottom: 18px;
        right: 18px;
        left: auto;
        width: 340px;
        border-radius: var(--r-card);
        border: 1px solid var(--line-mid);
        box-shadow: 0 18px 60px rgba(0, 0, 0, .5);
        transform: translateX(calc(100% + 40px));
        max-height: none;
      }

      #detail.show {
        transform: translateX(0);
      }
    }

    .detail-handle {
      width: 64px;
      height: 26px;
      display: flex;
      align-items: center;
      justify-content: center;
      margin: 2px auto 0;
      flex-shrink: 0;
      touch-action: none;
      cursor: grab;
    }

    .detail-handle::after {
      content: "";
      width: 40px;
      height: 3px;
      background: var(--soft-2);
      border-radius: var(--r-sm);
    }

    .panel-drag-handle {
      display: none;
      flex-shrink: 0;
      align-items: center;
      justify-content: center;
      padding: 14px 0 12px;
      touch-action: none;
      cursor: grab;
    }

    .panel-drag-handle span {
      width: 48px;
      height: 5px;
      background: var(--sheet-accent);
      border-radius: var(--r-sm);
    }

    /* The grab handles belong to the sheet world: below the line the list is a sheet,
       the list has a handle to drag it with; above it, the event is a card and has no
       handle at all. */
    @media (max-width: 900px) {
      .panel-drag-handle {
        display: flex;
      }
    }

    @media (min-width:901px) {
      .detail-handle {
        display: none;
      }
    }

    .detail-placeholder {
      display: none;
      flex: 1;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 10px;
      padding: 24px;
      color: var(--muted);
      text-align: center;
    }

    .detail-placeholder svg {
      opacity: .5;
    }

    .detail-placeholder span {
      font-family: var(--F-serif);
      font-style: italic;
      font-size: 14px;
      max-width: 220px;
      line-height: 1.5;
    }

    .detail-top {
      display: flex;
      align-items: flex-start;
      justify-content: space-between;
      padding: 20px 20px 10px;
      gap: 8px;
      flex-shrink: 0;
    }

    .detail-hero-image {
      display: block;
      width: 100%;
      /* The one ratio the site uses for photographs - see .pin-hero-image.

         Full-bleed here, but contained rather than covered. The sheet runs from a
         340px docked card to a 900px sheet, so any height that fills one of those
         is a crop at the other, and the sheet is where a person goes to see the
         thing itself. contain never cuts pixels, and on this palette the surface
         behind the picture is the same pure black, so the bars drawn when the
         ceiling engages are invisible. 46dvh exists only so a wide, short window
         cannot put a 500px banner above the fold; on a phone it never bites. */
      aspect-ratio: 16 / 9;
      height: auto;
      max-height: 46dvh;
      object-fit: contain;
      border-bottom: 1px solid var(--line-mid);
    }

    .pin-hero-image {
      display: block;
      width: 100%;
      /* One ratio site-wide: 16:9. It is what the phone cards have been pinned to
         all along, it is the nearest common ratio to the 1.91:1 social cards, and
         at a ~400px column it lands at 227px, which keeps a row of three inside a
         laptop. The card is the one surface that still crops on purpose - a grid is
         a grid because the frames agree - but the crop is the same crop for every
         event now, instead of whatever the id of the event happened to end in. */
      aspect-ratio: 16 / 9;
      height: auto;
      object-fit: cover;
      border-radius: 14px;
      /* Was var(--paper2), which no rule ever defined - so the frame behind a hero
         that is still loading (or 404s) was transparent, and the page showed
         through the hole the photo is supposed to fill. --soft is the one step of
         lift that reads as a frame rather than a mistake on a black card. */
      background: var(--soft);
    }

    /* The colour block that stands in when an event has no photo. It takes the
       same frame as a photo on purpose: the point of one ratio is that a card with
       an image and a card without one are the same shape - and with the inline
       height gone from the component, this is also the only thing keeping an
       image-less card off a zero-height block. */
    .pin-swatch {
      aspect-ratio: 16 / 9;
      border-radius: 14px;
    }

    .detail-cat {
      font-family: var(--F-sans);
      font-size: 8px;
      font-weight: 600;
      letter-spacing: .18em;
      text-transform: uppercase;
      border: 1px solid var(--ink);
      border-radius: var(--r-sm);
      padding: 4px 11px;
      display: inline-block;
      margin-bottom: 10px;
    }

    .detail-title {
      font-family: var(--F-display);
      font-size: 22px;
      font-weight: 500;
      line-height: 1.15;
      letter-spacing: -.02em;
    }

    .detail-close {
      background: none;
      border: 1px solid var(--line);
      border-radius: 50%;
      width: 32px;
      height: 32px;
      font-size: 16px;
      cursor: pointer;
      color: var(--muted);
      display: flex;
      align-items: center;
      justify-content: center;
      flex-shrink: 0;
      transition: color .2s, border-color .2s;
    }

    .detail-close:hover {
      color: var(--ink);
      border-color: var(--neon);
    }

    .detail-body {
      padding: 0 20px 24px;
      overflow-y: auto;
      flex: 1;
    }

    .detail-icon-block {
      height: 96px;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 48px;
      margin: 0 0 16px;
      border-radius: var(--r-sm);
      border: 1px solid var(--line);
    }

    .detail-meta {
      font-family: var(--F-sans);
      font-size: 11px;
      color: var(--muted);
      line-height: 1.9;
      margin-bottom: 14px;
      letter-spacing: .03em;
    }

    .detail-walk-route {
      display: inline-flex;
      align-items: center;
      gap: 4px;
      margin-left: 7px;
      color: var(--ink);
      font-weight: 700;
      white-space: nowrap;
      vertical-align: middle;
    }

    .detail-walk-route svg {
      flex-shrink: 0;
    }

    .detail-location {
      display: flex;
      align-items: baseline;
      gap: 6px;
      font-family: var(--F-sans);
      font-size: 13px;
      font-weight: 600;
      color: var(--ink);
      letter-spacing: 0;
      margin: 2px 0 6px;
    }

    .detail-location svg {
      flex-shrink: 0;
      margin-bottom: -1px;
    }

    .detail-desc {
      font-family: var(--F-serif);
      font-size: 15px;
      color: color-mix(in srgb, var(--ink) 82%, var(--paper));
      line-height: 1.65;
      margin-bottom: 16px;
    }

    .detail-ig {
      border-radius: var(--r-sm);
      overflow: hidden;
      background: var(--soft);
      border: 1px solid var(--line);
      margin-bottom: 14px;
      min-height: 280px;
      position: relative;
    }

    .detail-ig::before {
      content: "";
      position: absolute;
      top: 50%;
      left: 50%;
      width: 22px;
      height: 22px;
      margin: -11px 0 0 -11px;
      border: 2px solid var(--line);
      border-top-color: var(--ink);
      border-radius: 50%;
      animation: ig-spin .8s linear infinite;
    }

    .detail-ig.loaded::before {
      display: none;
    }

    @keyframes ig-spin {
      to {
        transform: rotate(360deg);
      }
    }

    .ig-paste-btn {
      background: var(--neon);
      color: #000;
      border: 1px solid var(--ink);
      border-radius: var(--r-sm);
      padding: 9px 12px;
      font-family: var(--F-sans);
      font-size: 8px;
      font-weight: 600;
      letter-spacing: .12em;
      text-transform: uppercase;
      cursor: pointer;
      white-space: nowrap;
    }

    /* LINK PREVIEW — live preview shown under Instagram / website link fields
       in the Add Event forms, so people can see what they're about to publish. */
    .link-preview {
      display: none;
      margin-top: 8px;
      margin-bottom: 14px;
      border: 1px solid var(--line);
      background: var(--soft);
      position: relative;
      overflow: hidden;
    }

    .link-preview.show {
      display: block;
    }

    .link-preview-site {
      display: flex;
      align-items: center;
      gap: 12px;
      padding: 13px 36px 13px 14px;
    }

    .link-preview-text {
      flex: 1;
      min-width: 0;
    }

    .link-preview-domain {
      font-family: var(--F-sans);
      font-size: 12px;
      font-weight: 600;
      color: var(--ink);
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    .link-preview-hint {
      font-family: var(--F-sans);
      font-size: 9px;
      color: var(--muted);
      letter-spacing: .04em;
      text-transform: uppercase;
      margin-top: 2px;
    }

    .link-preview-visit {
      flex-shrink: 0;
      font-family: var(--F-sans);
      font-size: 8px;
      font-weight: 600;
      letter-spacing: .12em;
      text-transform: uppercase;
      color: var(--ink);
      border: 1px solid var(--ink);
      padding: 7px 11px;
      text-decoration: none;
      white-space: nowrap;
      transition: background .15s, color .15s;
    }

    .link-preview-visit:hover {
      background: var(--neon);
      color: #000;
    }

    .detail-vibes {
      display: flex;
      gap: 6px;
      flex-wrap: wrap;
      margin-bottom: 16px;
    }

    .detail-vibe {
      font-size: 9px;
      padding: 4px 10px;
      border-radius: var(--r-sm);
      background: transparent;
      color: var(--muted);
      font-weight: 600;
      letter-spacing: .06em;
      text-transform: uppercase;
      border: 1px solid var(--line);
    }

    .detail-actions {
      display: flex;
      gap: 8px;
      flex-wrap: wrap;
      margin-top: 16px;
      padding-top: 16px;
      border-top: 1px solid var(--line);
    }

    .detail-btn {
      display: inline-flex;
      align-items: center;
      gap: 5px;
      padding: 10px 15px;
      border-radius: var(--r-sm);
      font-family: var(--F-sans);
      font-size: 8px;
      font-weight: 600;
      letter-spacing: .13em;
      text-transform: uppercase;
      cursor: pointer;
      border: 1px solid var(--line-mid);
      background: transparent;
      color: var(--ink);
      transition: background .2s, color .2s;
      text-decoration: none;
    }

    .detail-btn:hover,
    .detail-btn.saved {
      background: var(--neon);
      color: #000;
    }

    .detail-btn.going-btn {
      border-color: var(--neon);
      color: var(--ink);
    }

    .detail-btn.going-btn:hover,
    .detail-btn.going-btn.active {
      background: var(--neon);
      color: #000;
      border-color: var(--neon);
    }

    /* Search */
    #search-overlay {
      display: none;
      position: fixed;
      inset: 0;
      background: rgba(0, 0, 0, .92);
      backdrop-filter: blur(14px);
      -webkit-backdrop-filter: blur(14px);
      z-index: 200;
      padding: 100px 48px 40px;
      backdrop-filter: blur(6px);
    }

    #search-overlay.open {
      display: block;
    }

    .so-close {
      position: absolute;
      top: 28px;
      right: 36px;
      font-size: 20px;
      background: none;
      border: 1px solid var(--ink);
      border-radius: 50%;
      width: 46px;
      height: 46px;
      cursor: pointer;
      color: var(--ink);
      display: flex;
      align-items: center;
      justify-content: center;
      transition: background .2s, color .2s;
    }

    .so-close:hover {
      background: var(--neon);
      color: #000;
    }

    .so-input {
      width: 100%;
      max-width: 1000px;
      margin: 0 auto;
      display: block;
      border: none;
      border-bottom: 1px solid var(--ink);
      background: transparent;
      font-family: var(--F-display);
      font-size: clamp(28px, 5vw, 52px);
      font-weight: 300;
      text-transform: lowercase;
      letter-spacing: -.03em;
      padding: 12px 0;
      outline: none;
      color: var(--ink);
    }

    .so-input::placeholder {
      color: var(--muted);
    }

    .so-results {
      margin: 40px auto 0;
      max-width: 1000px;
    }

    .so-item {
      padding: 20px 0;
      border-bottom: 1px solid var(--line);
      cursor: pointer;
      transition: opacity .15s;
    }

    .so-item:hover {
      opacity: .55;
    }

    .so-title {
      font-family: var(--F-display);
      font-size: 20px;
      font-weight: 500;
      letter-spacing: -.015em;
    }

    .so-meta {
      font-family: var(--F-sans);
      font-size: 10px;
      color: var(--muted);
      margin-top: 6px;
      letter-spacing: .12em;
      text-transform: uppercase;
    }

    .so-empty {
      font-family: var(--F-serif);
      font-style: italic;
      font-size: 18px;
      font-weight: 300;
      color: var(--muted);
      margin-top: 40px;
      text-transform: lowercase;
    }

    /* Square off rounded inline styles in the home add-event form */
    #sp-addevent input,
    #sp-addevent select,
    #sp-addevent textarea,
    #add-success-home {
      border-radius: 0 !important;
      border-color: var(--line) !important;
    }

    #sp-addevent input:focus,
    #sp-addevent select:focus,
    #sp-addevent textarea:focus {
      border-color: var(--neon) !important;
    }

    #theme-btn {
      display: none !important;
    }

    @media (max-width:900px) {

      .masonry,
      .saved-masonry {
        grid-template-columns: 1fr 1fr;
        gap: 20px;
      }

      #panel {
        position: absolute;
        top: 0;
        bottom: 0;
        z-index: 30;
      }

      #panel-toggle {
        display: none;
      }
    }

    /* ── MOBILE ── */
    @media (max-width:600px) {
      :root {
        --top-h: 54px;
      }

      #topbar {
        padding: 0;
        gap: 0;
      }

      .tb-logo {
        min-width: auto;
        padding: 0 16px;
        border-right: none;
      }

      .tb-center {
        display: none !important;
      }

      .tb-right {
        border-left: none;
        padding: 0 12px;
        gap: 8px;
        /* The centre nav is hidden here and the burger that used to fill the right
           hand side is gone, so the two controls that stay — search and language —
           have to be pushed to the edge or they crowd the logo. */
        margin-left: auto;
      }

      /* The wordy header buttons are what the burger used to carry; the account icon
         is the exception, because the bottom bar only offers sign-in while nobody is
         signed in and this is the way back out again. */
      .tb-btn:not(.solid):not(#lang-btn):not(.tb-account) {
        display: none;
      }

      .tb-btn.tb-account {
        min-width: 44px;
        min-height: 44px;
        padding: 0;
        justify-content: center;
      }

      #lang-btn {
        min-width: 38px;
        padding: 0 8px;
        font-size: 9px;
        height: 34px;
      }

      .tb-btn.solid {
        padding: 0 14px;
        font-size: 8px;
        height: 34px;
      }

      #mobile-nav {
        display: flex;
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        /* The bar reaches the physical bottom of the screen, and the home indicator is
           padding inside it rather than a gap under it. `bottom: 0` alone stops at the top
           of the safe area: iOS reports the layout viewport as ending there, so the strip
           between the bar and the edge of the glass is painted by `body` — black, while the
           bar has been a deliberate #2a2a2a ever since it stopped being black to match the
           page. That is the whole of the "the navbar floats above the bottom" report, and it
           is iPhone-only because Android draws its own navigation bar into the viewport
           instead of reserving a strip outside it. The height grows by the inset and the
           inset comes back off the content box as padding, so what a thumb gets is still the
           same 58px strip with the labels in it, now with the indicator resting in the
           border below them. `env()` resolves to 0 everywhere there is no cutout, and needs
           viewport-fit=cover in the viewport meta to be anything at all (index.html). */
        height: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px));
        padding-bottom: env(safe-area-inset-bottom, 0px);
        /* One step up from the page rather than the same black as it. The bar used to
           be var(--card), which on this palette is #000000 — the same colour as
           var(--paper) behind it — so the only thing telling you where the bar started
           was a hairline, and content scrolling under the edge was indistinguishable
           from the bar itself. --soft (#0e0e0e) is too small a step to read on a phone
           screen, and so was the first answer: #141414 measured a 1.14 surface ratio
           against the page, which on a phone held up to daylight is still the page
           running under your thumb. #2a2a2a is 1.47 — unmistakably a strip — while the
           sheets that slide over it stay var(--card), so the chrome reads lighter than
           content and never competes with a sheet for the same grey. */
        background: #2a2a2a;
        border-top: 1px solid var(--line-mid);
        z-index: 100;
        box-shadow: none;
      }

      #mobile-nav button {
        flex: 1;
        border: none;
        background: none;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 4px;
        font-family: var(--F-sans);
        font-size: 7px;
        font-weight: 600;
        letter-spacing: .12em;
        text-transform: uppercase;
        /* A lighter bar spends label contrast: var(--muted) on the old #141414 measured
           5.75:1 and on this fill 4.48:1, which is under the 4.5 that seven 8px
           uppercase words have to clear. #9a9aa3 is back to 5.1:1 — and still a long way
           under the pure white an active item wears (16.4:1 here), plus its scale, so
           which tab you are on stays the brightest thing in the bar. */
        color: #9a9aa3;
        cursor: pointer;
        transition: color .2s;
        padding: 0;
      }

      #mobile-nav button .mn-icon {
        font-size: 18px;
        line-height: 1;
      }

      #mobile-nav button span {
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }

      #mobile-nav button.active {
        color: var(--ink);
      }

      #mobile-nav button.active .mn-icon {
        transform: scale(1.05);
      }

      #home-page {
        padding-bottom: calc(66px + env(safe-area-inset-bottom, 0px));
      }

      .sub-page {
        padding-bottom: calc(80px + env(safe-area-inset-bottom, 0px)) !important;
      }

      .hero {
        min-height: 0;
        padding: 30px 0 10px;
      }

      .hero-logo-wrap {
        padding: 0 8px;
      }

      .krug-acro {
        margin-top: 8px;
      }

      .hero-circle {
        margin-top: 10px;
      }

      .sec-head {
        margin-top: 26px;
      }

    .hero-eyebrow {
        margin-bottom: 20px;
      }

      .lbl {
        font-size: 9px;
        letter-spacing: .28em;
      }

      .hero-circle {
        width: 84px;
        height: 84px;
        font-size: 9px;
        margin: 36px auto 0;
      }

      .home-inner {
        padding: 0 16px 24px;
      }

      .sec-head {
        font-size: clamp(28px, 9vw, 48px);
        margin-top: 84px;
      }

      .tabs {
        margin: 24px 0 20px;
        gap: 20px;
      }

      .tabs button {
        font-size: 12px;
      }

      .masonry {
        display: flex;
        flex-direction: column;
        gap: 0;
        margin-top: 24px !important;
        border-top: 1px solid var(--line);
      }

      .pin {
        display: grid;
        grid-template-columns: 76px 1fr;
        grid-template-rows: auto;
        border-radius: var(--r-sm);
        padding: 0 0 14px;
        align-items: stretch;
        min-height: 84px;
        border-bottom: 1px solid var(--line);
      }

      .pin:hover {
        opacity: 1;
      }

      .pin>div:first-child {
        grid-column: 1;
        grid-row: 1/99;
        border-radius: 0 !important;
        height: auto !important;
        min-height: 84px;
        font-size: 30px !important;
        border-right: 1px solid var(--line);
      }

      .pin h3 {
        grid-column: 2;
        font-size: 15px;
        line-height: 1.25;
        margin: 14px 14px 0;
      }

      .pin p {
        grid-column: 2;
        font-size: 9px;
        margin: 5px 14px 0;
        line-height: 1.5;
      }

      .vibe-tags {
        grid-column: 2;
        margin: 7px 14px 0;
        gap: 5px;
      }

      .vibe-tag {
        font-size: 8px;
        padding: 2px 7px;
      }

      .save-count {
        grid-column: 2;
        margin: 5px 14px 8px;
        font-size: 9px;
      }

      .star-rating {
        grid-column: 2;
      }

      /* Removed: `.pin>div:last-of-type:not(:first-child) { margin: 0 14px 10px }`.
         It belonged to the abandoned 76px thumbnail column, whose grid areas it
         placed. On the card that replaced that column it outvoted every plain
         `.vibe-tags` / `.star-rating` / `.save-count` rule in the file and pinned
         whichever of them came last flush against the line above it. */

      .heart-btn {
        width: 32px;
        height: 32px;
        font-size: 13px;
        right: 10px;
        top: 10px;
      }

      .saved-masonry {
        display: flex;
        flex-direction: column;
        gap: 0;
        border-top: 1px solid var(--line);
      }

      .tonight-row {
        grid-template-columns: 70px 1fr;
      }

      .tonight-time-col {
        padding: 16px 0;
      }

      .tonight-time {
        font-size: 13px;
      }

      .tonight-info {
        padding: 16px 14px;
      }

      .tonight-title {
        font-size: 16px;
      }

      .tonight-meta {
        font-size: 9px;
      }

      .past-row {
        grid-template-columns: 70px 1fr;
      }

      .past-info {
        padding: 14px 14px;
      }

      .past-title {
        font-size: 14px;
      }

      .sub-page {
        padding: 36px 16px 80px;
      }

      .sub-page h1 {
        font-size: clamp(42px, 15vw, 96px);
      }

      .sub-page-sub {
        font-size: 14px;
        margin-bottom: 28px;
      }

      .krug-footer {
        flex-direction: column;
        align-items: center;
      text-align: center;
      gap: 12px;
      padding: 28px 24px 86px;
      margin-top: auto;
    }

      /* The map and the two sheets that ride it — the list, and the event laid over
         it — are laid out together at the end of this file, on one width. They used to
         be split between 600px here and 699px there, which left the widths in between
         with the list as an overlay window and the event as a sheet at the same time:
         two panels on one screen, and the panel's own toggle is hidden at that width,
         so neither could be dismissed. */

      #ctrl-locate-label {
        font-size: 9px;
      }

      #search-overlay {
        padding: 72px 20px 20px;
      }

      .so-close {
        top: 16px;
        right: 18px;
        width: 38px;
        height: 38px;
        font-size: 18px;
      }

      .rate-box {
        border-radius: var(--r-sm);
        padding: 28px 22px;
      }

      .quote {
        font-size: 18px;
        padding-top: 28px;
        margin-top: 48px;
      }
    }
    /* ═══ SHOTGUN LAYER — dark chrome, aurora glow, pills ═══ */

    #app {
      position: relative;
      z-index: 1;
      /* Clears the top bar, which is that height plus whatever the device takes at the top. */
      padding-top: calc(var(--top-h) + env(safe-area-inset-top, 0px));
    }

    /* Pill controls, Shotgun-style */
    .tb-btn,
    .chip,
    .vchip,
    .vibe-chip,
    .detail-btn,
    .surprise-btn,
    .add-submit,
    .rate-submit,
    .ai-btn,
    .ig-paste-btn,
    .link-preview-visit,
    .confirm-cancel,
    .confirm-delete,
    .mine-delete,
    #ctrl-locate {
      border-radius: var(--r-pill);
    }

    .heart-btn,
    .so-close {
      border-radius: 50%;
    }

    /* Rounded surfaces */
    .rate-box,
    .confirm-box,
    .link-preview,
    .map-ctrl {
      border-radius: var(--r-card);
    }

    .rate-box,
    .confirm-box {
      border-color: var(--line-mid);
      box-shadow: 0 24px 80px rgba(0, 0, 0, .55);
    }

    #ctrl-zoom {
      overflow: hidden;
    }

    /* Event cards: lift on hover instead of fading */
    .pin:hover {
      opacity: 1;
      transform: translateY(-4px);
      border-color: var(--line-mid);
      box-shadow: 0 18px 48px rgba(0, 0, 0, .45);
    }

    /* Toggle knob readable on the white "on" track */

    /* Hero circle: aurora ring on hover */
    .hero-circle:hover {
      border-color: var(--neon);
      color: var(--neon);
      box-shadow: 0 0 24px rgba(255, 255, 255, .35);
    }

    /* Dark OpenStreetMap chrome */
    .maplibregl-map {
      background: #050506;
      font-family: var(--F-sans);
    }

    #map-el.maplibregl-map,
    #map-el {
      z-index: 1;
      isolation: isolate;
    }

    #map-el .maplibregl-canvas {
      filter: contrast(1.03) saturate(.88);
      outline: none;
    }

    #map-el .maplibregl-marker {
      z-index: 20;
    }

    .krug-event-marker {
      appearance: none;
      position: relative;
      display: block;
      width: 11px;
      height: 11px;
      padding: 0;
      border: 0;
      border-radius: 50%;
      background: var(--marker-color, #fff);
      box-shadow: 0 2px 6px rgba(0, 0, 0, .55), 0 0 0 1.5px rgba(0, 0, 0, .4);
      cursor: pointer;
      transform: scale(1);
      transition: width .18s ease, height .18s ease, box-shadow .18s ease, transform .18s ease;
    }

    .krug-event-marker::after {
      content: "";
      position: absolute;
      inset: -10px;
      border-radius: 50%;
    }

    .krug-event-marker.selected {
      width: 16px;
      height: 16px;
      box-shadow: 0 2px 6px rgba(0, 0, 0, .55), 0 0 0 3px #fff;
      transform: scale(1.15);
    }

    .map-ctrl,
    #ctrl-locate,
    #ctrl-zoom {
      z-index: 40;
    }

    #detail {
      z-index: 50;
    }

    .maplibregl-ctrl-attrib {
      background: rgba(0, 0, 0, .55) !important;
      color: #aaa !important;
    }

    .maplibregl-ctrl-attrib a {
      color: #aaa !important;
    }

    /* Scrollbars */
    * {
      scrollbar-width: thin;
      scrollbar-color: var(--soft-2) transparent;
    }

    ::-webkit-scrollbar {
      width: 10px;
      height: 10px;
    }

    ::-webkit-scrollbar-thumb {
      background: var(--soft-2);
      border-radius: 99px;
      border: 3px solid var(--paper);
    }

    ::-webkit-scrollbar-track {
      background: transparent;
    }

    /* ═══ TRAUM LAYER — mono, flat black, neon states ═══ */

    .hero-logo-wrap {
      width: 100%;
      padding: 0 2vw;
      margin: 0 auto;
      line-height: 0;
    }

    .hero-logo {
      display: block;
      width: 100%;
      height: auto;
    }

    /* Bottom fade: content melts into black at the base of the screen */
    body::after {
      content: "";
      position: fixed;
      left: 0;
      right: 0;
      bottom: 0;
      height: 140px;
      z-index: 35;
      pointer-events: none;
      background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, .65) 62%, rgba(0, 0, 0, .95) 100%);
    }

    /* ═══ PAGE BACKGROUNDS ═══
   Views sit directly on the plain black page background (html/body use
   --paper: #000000) — the old per-view photo overlays are gone. */

    #sp-home {
      position: relative;
    }

    .hero {
      padding-bottom: 56px;
    }

    /* ═══ LOGO TAGLINE — "Your 3rd place" under TH3, the acronym under KRUG ═══
       column widths follow the logo artwork: TH3 = 0–39.3%, KRUG = 42.4–100% */
    .krug-acro {
      justify-content: space-between;
      align-items: center;
      gap: 0;
      padding: 0 2vw;
    }

    .krug-acro .kt-place,
    .krug-acro .kt-acro {
      display: flex;
      justify-content: space-between;
      align-items: center;
      white-space: nowrap;
    }

    .krug-acro .kt-place { width: 39.3%; justify-content: flex-start; gap: .55em; padding-left: 3.33%; } /* together, starting under the T's stem */
    .krug-acro .kt-acro { width: 57.6%; }
    /* letter-spacing leaves a gap after the last letter; pull it back so
       "Generation" ends exactly at the G's right edge (99.86% of the artwork) */
    .krug-acro .kt-acro > span:last-child { margin-right: calc(-1em * var(--acro-track, .18) + .14%); }

    #gate .krug-acro {
      width: min(86vw, 720px);
      padding: 0;
      margin: 0;
      font-size: 10px;
      letter-spacing: .14em;
      --acro-track: .14;
      color: var(--muted);
    }

    @media (max-width: 600px) {
      .krug-acro {
        padding: 0 8px;
        font-size: 7.5px;
        letter-spacing: .08em;
        --acro-track: .08;
      }

      .krug-acro .kt-acro i { display: none; }

      #gate .krug-acro { font-size: 7px; letter-spacing: .06em; --acro-track: .06; }
      #gate .krug-acro .kt-acro i { display: none; }
    }

    /* ═══ KRUG CROWD — canvas of circles behind the hero ═══ */
    .krug-crowd {
      position: fixed;
      top: 0;
      left: 0;
      z-index: 0;
      pointer-events: none;
    }

    .hero > .hero-eyebrow {
      position: relative;
      z-index: 2;
    }

    /* phones: one even rhythm from "СОФИЯ" down to the heading */
    @media (max-width: 600px) {
      #sp-home .hero { min-height: 0; padding-bottom: 0; }
      #sp-home .hero-eyebrow { margin-bottom: 0; }
      #sp-home .hero-logo-wrap { margin-top: var(--m-gap); }
      #sp-home .hero-circle { margin-top: var(--m-gap); }
      #sp-home .home-inner > .sec-head { margin-top: var(--m-gap); }
      #sp-home { --m-gap: 34px; }
    }

    /* everything below the hero sits above the circles; no z-index on the wrapper
       itself, so the big titles can still blend with the circles behind them */
    .home-inner > * {
      position: relative;
      z-index: 1;
    }

    /* big titles: white letters turn a passing circle black where they overlap */
    .hero-logo-wrap,
    .home-inner > .sec-head {
      mix-blend-mode: difference;
    }

    /* ═══ LAUNCH GATE ═══ */
    #gate {
      position: fixed;
      inset: 0;
      z-index: 100002;
      background-color: #000;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 18px;
      padding: 28px;
      text-align: center;
      transition: opacity .6s, visibility .6s;
    }

    #gate.open {
      opacity: 0;
      visibility: hidden;
      pointer-events: none;
    }

    body.gated {
      overflow: hidden;
    }

    .gate-clock {
      font-family: var(--F-sans);
      font-size: 12px;
      letter-spacing: .3em;
      color: var(--muted);
      font-variant-numeric: tabular-nums;
    }

    .gate-logo {
      width: min(86vw, 720px);
      height: auto;
      display: block;
    }

    .gate-sub {
      font-family: var(--F-sans);
      font-size: 11px;
      letter-spacing: .3em;
      text-transform: uppercase;
      color: var(--muted);
    }

    .gate-label {
      margin-top: 16px;
      font-family: var(--F-sans);
      font-size: 10px;
      letter-spacing: .26em;
      text-transform: uppercase;
      color: var(--ink);
      border: 1px solid var(--line-mid);
      border-radius: var(--r-pill);
      padding: 8px 18px;
    }

    .gate-count {
      display: flex;
      align-items: baseline;
      gap: 14px;
      margin-top: 4px;
    }

    .gc b {
      font-family: var(--F-display);
      font-size: clamp(30px, 7vw, 64px);
      font-weight: 800;
      color: var(--ink);
      font-variant-numeric: tabular-nums;
      display: block;
      line-height: 1;
    }

    .gc span {
      display: block;
      margin-top: 8px;
      font-family: var(--F-sans);
      font-size: 9px;
      letter-spacing: .24em;
      text-transform: uppercase;
      color: var(--muted);
    }

    .gc-sep {
      font-family: var(--F-display);
      font-size: clamp(22px, 5vw, 44px);
      color: var(--muted);
      align-self: flex-start;
    }

    #gate-form {
      display: flex;
      gap: 10px;
      margin-top: 26px;
      width: min(86vw, 380px);
    }

    #gate-pass {
      flex: 1;
      background: transparent;
      border: none;
      border-bottom: 1px solid var(--line-mid);
      color: var(--ink);
      font-family: var(--F-sans);
      font-size: 14px;
      letter-spacing: .1em;
      padding: 10px 2px;
      text-align: center;
    }

    #gate-pass:focus {
      outline: none;
      border-bottom-color: var(--ink);
    }

    #gate-form button {
      border: 1px solid var(--line-mid);
      background: transparent;
      color: var(--ink);
      font-family: var(--F-sans);
      font-size: 11px;
      letter-spacing: .2em;
      text-transform: uppercase;
      padding: 10px 20px;
      border-radius: var(--r-pill);
      cursor: pointer;
      transition: background .2s, color .2s;
    }

    #gate-form button:hover {
      background: var(--ink);
      color: #000;
    }

    @media (max-width: 600px) {
      #gate {
        gap: 14px;
        padding: 20px;
      }

      .gate-clock {
        font-size: 10px;
        letter-spacing: .22em;
      }

      .gate-label {
        margin-top: 8px;
        font-size: 9px;
      }

      .gate-count {
        gap: 8px;
      }

      .gc span {
        font-size: 8px;
        letter-spacing: .14em;
      }
    }

    .cat-dot {
      display: inline-block;
      width: 6px;
      height: 6px;
      border-radius: 50%;
      border: 1.5px solid rgba(0, 0, 0, .55);
      vertical-align: middle;
    }

    .event-dot {
      width: 6px;
      height: 6px;
      border-radius: 50%;
      flex-shrink: 0;
      align-self: center;
      border: 1.5px solid rgba(0, 0, 0, .55);
    }

    .event-row.selected .event-dot {
      border-color: rgba(0, 0, 0, .55);
      box-shadow: 0 0 0 2px rgba(0, 0, 0, .15);
    }

    /* + ADD EVENT: the one solid, unmissable button in the nav */
    #topbar .tb-btn.solid {
      background: var(--ink) !important;
      color: #000 !important;
      border-radius: var(--r-pill);
      padding: 12px 24px;
      font-size: 12px;
      font-weight: 800;
      letter-spacing: .12em;
      box-shadow: 0 4px 18px rgba(255, 255, 255, .18);
      transform: translateZ(0);
      transition: transform .15s, box-shadow .15s;
    }

    #topbar .tb-btn.solid:hover {
      background: var(--ink) !important;
      color: #000 !important;
      transform: scale(1.05);
      box-shadow: 0 6px 26px rgba(255, 255, 255, .3);
    }

    @media (max-width: 600px) {
      #topbar .tb-btn.solid {
        padding: 10px 18px;
        font-size: 11px;
      }
    }

    .city-switch {
      display: flex;
      justify-content: center;
      align-items: center;
      gap: 10px;
      margin: 14px 0 2px;
      font-family: var(--F-sans);
      flex-wrap: wrap;
    }

    .city-switch button {
      border: none;
      background: none;
      color: var(--muted);
      font-family: var(--F-sans);
      font-size: 12px;
      font-weight: 600;
      letter-spacing: .14em;
      text-transform: uppercase;
      cursor: pointer;
      padding: 4px 2px;
    }

    .city-switch button:hover,
    .city-switch button.active {
      color: var(--ink);
      border-bottom: 1px solid var(--ink);
    }

    .cs-sep {
      color: var(--muted);
      opacity: .5;
    }

    .map-tonight-btn {
      display: flex;
      align-items: center;
      gap: 7px;
      width: fit-content;
      margin: 0 0 12px 20px;
      border: 1px solid var(--line-strong);
      background: transparent;
      color: var(--ink);
      font-family: var(--F-sans);
      font-size: 11px;
      font-weight: 700;
      letter-spacing: .1em;
      text-transform: uppercase;
      padding: 8px 16px;
      border-radius: var(--r-pill);
      cursor: pointer;
      transition: background .15s, color .15s;
    }

    .map-tonight-btn:hover {
      background: var(--ink);
      color: var(--on-ink);
    }

    .panel-cities {
      margin-bottom: 2px;
      padding-bottom: 0;
      border-bottom: none;
    }

    /* Wraps the two day shortcuts in the map panel header: "today" and "this week" side by
       side. They wrap instead of shrinking because the Bulgarian labels are wider than the
       English ones, and a squeezed pill breaks its own text mid-word. */
    .panel-topbar-mobile {
      display: flex;
      align-items: center;
      flex-wrap: wrap;
      gap: 8px;
      padding: 16px 20px 10px;
    }

    .panel-topbar-mobile .map-tonight-btn {
      margin: 0;
      flex-shrink: 0;
      white-space: nowrap;
    }

    /* Inside the list sheet: the filter stack and the mobile top bar of the panel.
       These travel with the sheet, so they switch at 900px with it. */
    @media (max-width:900px) {
      .panel-view {
        position: relative;
      }

      .panel-topbar-mobile {
        padding: 0 16px 10px;
      }

      .map-filter-stack {
        padding: 10px 16px;
        gap: 8px;
      }

      .map-filter-clear span {
        display: none;
      }
    }

    .city-head {
      font-family: var(--F-display);
      font-size: clamp(18px, 3vw, 28px);
      font-weight: 800;
      text-transform: uppercase;
      margin: 34px 0 10px;
    }

    .city-head:first-child {
      margin-top: 6px;
    }

    .allday-row {
      align-items: center;
    }

    .allday-check {
      display: flex;
      align-items: center;
      gap: 8px;
      font-family: var(--F-sans);
      font-size: 11px;
      color: var(--muted);
      cursor: pointer;
      white-space: nowrap;
    }

    .allday-check input {
      width: 16px;
      height: 16px;
      accent-color: var(--ink);
      cursor: pointer;
    }

.myevents-subhead {
      margin-top: 56px;
      padding-top: 28px;
      border-top: 1px solid var(--line-mid);
    }

    .tb-search-icon-btn {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 34px;
      height: 34px;
      border: none;
      background: transparent;
      color: var(--ink);
      cursor: pointer;
      border-radius: 50%;
      flex-shrink: 0;
      transition: background .15s, color .15s;
    }

    .tb-search-icon-btn:hover {
      background: rgba(255, 255, 255, .08);
      color: var(--neon);
    }

    .chip-dot {
      display: inline-block;
      width: 6px;
      height: 6px;
      border-radius: 50%;
      margin-right: 7px;
      vertical-align: baseline;
    }

    /* Event photo gallery + admin panel */
    .d-photos-title {
      font-family: var(--F-sans);
      font-size: 10px;
      font-weight: 600;
      letter-spacing: .16em;
      text-transform: uppercase;
      color: var(--muted);
      margin: 18px 0 10px;
    }

    .d-photos {
      display: flex;
      gap: 8px;
      overflow-x: auto;
      padding-bottom: 6px;
      -webkit-overflow-scrolling: touch;
    }

    .d-photos a {
      flex: 0 0 auto;
      line-height: 0;
    }

    .d-photos img {
      height: 104px;
      width: auto;
      max-width: 180px;
      object-fit: cover;
      border-radius: 10px;
      border: 1px solid var(--line);
    }

    .d-photos-empty {
      font-family: var(--F-sans);
      font-size: 12px;
      color: var(--muted);
      padding: 8px 0;
    }

    .photo-add-row {
      display: flex;
      gap: 8px;
      margin-top: 10px;
    }

    .admin-zone {
      margin-top: 56px;
      padding-top: 26px;
      border-top: 1px solid var(--line-mid);
    }

    .admin-users-panel {
      border: 1px solid var(--line-mid);
      padding: 14px;
    }

    .admin-import-panel {
      display: grid;
      gap: 10px;
      border: 1px solid var(--line-mid);
      padding: 14px;
    }

    .admin-moderation-panel {
      display: grid;
      gap: 14px;
      border: 1px solid var(--line-mid);
      padding: 14px;
    }

    .admin-moderation-list {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
      gap: 0 18px;
      border-bottom: 1px solid var(--line);
    }

    .admin-moderation-row {
      display: grid;
      grid-template-columns: minmax(0, 1fr) 108px;
      align-items: center;
      gap: 12px;
      min-height: 58px;
      border-top: 1px solid var(--line);
      font-family: var(--F-sans);
    }

    .admin-moderation-toggle {
      display: grid;
      grid-template-columns: 18px minmax(0, 1fr);
      align-items: center;
      gap: 2px 8px;
      cursor: pointer;
    }

    .admin-moderation-toggle input {
      grid-row: 1 / 3;
      width: 16px;
      height: 16px;
      accent-color: var(--ink);
    }

    .admin-moderation-toggle span {
      overflow-wrap: anywhere;
      color: var(--ink);
      font-size: 12px;
      font-weight: 700;
    }

    .admin-moderation-toggle small {
      color: var(--muted);
      font-size: 10px;
    }

    .admin-moderation-threshold {
      display: grid;
      gap: 4px;
      color: var(--muted);
      font-size: 9px;
      font-weight: 700;
      text-transform: uppercase;
    }

    .admin-moderation-threshold input {
      width: 100%;
      height: 30px;
      border: 1px solid var(--line-mid);
      border-radius: var(--r-sm);
      background: transparent;
      color: var(--ink);
      padding: 0 7px;
      font-family: var(--F-sans);
      font-size: 12px;
    }

    @media (max-width: 480px) {
      .admin-moderation-row {
        grid-template-columns: minmax(0, 1fr) 96px;
      }

      .admin-import-actions {
        flex-wrap: wrap;
      }
    }

    .admin-import-heading {
      display: flex;
      align-items: flex-start;
      justify-content: space-between;
      gap: 16px;
    }

    .admin-import-heading div {
      display: grid;
      gap: 4px;
    }

    .admin-import-heading strong,
    .admin-import-panel label {
      font-family: var(--F-sans);
      font-size: 10px;
      font-weight: 700;
      letter-spacing: .1em;
      text-transform: uppercase;
    }

    .admin-import-heading span {
      color: var(--muted);
      font-family: var(--F-sans);
      font-size: 11px;
      line-height: 1.5;
    }

    .admin-import-editor {
      width: 100%;
      min-height: 520px;
      resize: vertical;
      border: 1px solid var(--line-mid);
      border-radius: var(--r-sm);
      background: var(--paper2);
      color: var(--ink);
      padding: 14px;
      font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
      font-size: 12px;
      line-height: 1.55;
      tab-size: 2;
      outline: none;
    }

    .admin-import-editor:focus {
      border-color: var(--line-strong);
    }

    .admin-import-error {
      border-left: 3px solid var(--red);
      padding: 8px 10px;
      color: var(--red);
      font-family: var(--F-sans);
      font-size: 11px;
      line-height: 1.5;
    }

    .admin-import-actions {
      display: flex;
      justify-content: flex-end;
      gap: 8px;
    }

    .admin-import-source,
    .admin-import-json {
      display: grid;
      gap: 10px;
    }

    .admin-import-step-tag {
      display: inline-flex;
      align-items: center;
      gap: 8px;
      color: var(--muted);
      font-family: var(--F-sans);
      font-size: 9px;
      font-weight: 700;
      letter-spacing: .16em;
      text-transform: uppercase;
    }

    .admin-import-step-tag span {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      width: 18px;
      height: 18px;
      border: 1px solid var(--line-mid);
      border-radius: 50%;
      color: var(--ink);
      font-size: 10px;
      letter-spacing: 0;
    }

    .admin-import-url-row {
      display: flex;
      align-items: stretch;
      gap: 8px;
    }

    .admin-import-url-row input {
      flex: 1 1 auto;
      min-width: 0;
      height: 38px;
      border: 1px solid var(--line-mid);
      border-radius: var(--r-sm);
      background: var(--field);
      color: var(--ink);
      padding: 0 12px;
      font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
      font-size: 12px;
      outline: none;
    }

    .admin-import-url-row input:focus {
      border-color: var(--line-strong);
    }

    .admin-import-url-row input::placeholder {
      color: var(--muted);
      font-family: var(--F-sans);
    }

    .admin-import-sites {
      display: flex;
      align-items: center;
      flex-wrap: wrap;
      gap: 6px;
      color: var(--muted);
      font-family: var(--F-sans);
      font-size: 10px;
      font-weight: 700;
      letter-spacing: .1em;
      text-transform: uppercase;
    }

    .admin-import-sites code {
      border: 1px solid var(--line-mid);
      border-radius: var(--r-sm);
      padding: 2px 6px;
      color: var(--ink);
      font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
      font-size: 10px;
      letter-spacing: 0;
      text-transform: none;
    }

    .admin-import-guide {
      display: grid;
      gap: 10px;
      border: 1px solid var(--line-mid);
      border-left: 3px solid var(--neon);
      border-radius: var(--r-sm);
      background: var(--soft);
      padding: 12px 14px;
    }

    .admin-import-guide-head {
      display: flex;
      align-items: flex-start;
      gap: 10px;
    }

    .admin-import-guide-head div {
      display: grid;
      gap: 2px;
    }

    .admin-import-guide-head strong {
      font-family: var(--F-sans);
      font-size: 10px;
      font-weight: 700;
      letter-spacing: .1em;
      text-transform: uppercase;
    }

    .admin-import-guide-head span {
      color: var(--muted);
      font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
      font-size: 11px;
      overflow-wrap: anywhere;
    }

    .admin-import-guide-list {
      display: grid;
      gap: 6px;
      margin-left: 18px;
      color: var(--ink);
      font-family: var(--F-sans);
      font-size: 12px;
      line-height: 1.5;
    }

    .admin-import-guide-list li::marker {
      color: var(--muted);
      font-weight: 700;
    }

    .admin-import-guide-actions {
      display: flex;
      flex-wrap: wrap;
      gap: 8px;
    }

    .admin-import-notice {
      border-left: 3px solid var(--line-strong);
      padding: 6px 10px;
      color: var(--muted);
      font-family: var(--F-sans);
      font-size: 11px;
      line-height: 1.5;
    }

    .admin-import-prompt summary {
      cursor: pointer;
      color: var(--muted);
      font-family: var(--F-sans);
      font-size: 10px;
      font-weight: 700;
      letter-spacing: .1em;
      text-transform: uppercase;
    }

    .admin-import-prompt-text {
      width: 100%;
      max-height: 260px;
      margin-top: 8px;
      resize: vertical;
      border: 1px solid var(--line-mid);
      border-radius: var(--r-sm);
      background: var(--field);
      color: var(--muted);
      padding: 12px;
      font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
      font-size: 11px;
      line-height: 1.55;
      white-space: pre-wrap;
      outline: none;
    }

    @media (max-width: 640px) {
      .admin-import-url-row {
        flex-direction: column;
      }

      .admin-import-url-row input {
        width: 100%;
      }
    }

    .event-hero-upload {
      border-top: 1px solid var(--line-mid);
      padding-top: 16px;
    }

    .event-hero-upload input[type="file"] {
      width: 100%;
      color: var(--muted);
      font-family: var(--F-sans);
      font-size: 11px;
    }

    .event-hero-preview {
      display: block;
      width: 100%;
      /* Contained, never covered. This is the one surface where a person is being
         shown the file itself, and until now it cropped to a 3.4:1 slit at the full
         952px form width - a preview that lied about an image the server had stored
         whole. It is also drawn at the site ratio with a visible frame, so it does
         double duty as the spec: what falls outside this box is what the card will
         crop, and the whole upload is still visible while you decide. */
      aspect-ratio: 16 / 9;
      height: auto;
      max-width: 640px;
      margin-bottom: 10px;
      object-fit: contain;
      background: var(--field);
      border: 1px solid var(--line-mid);
      border-radius: var(--r-sm);
    }

    .event-hero-file {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 12px;
      color: var(--ink);
      font-family: var(--F-sans);
      font-size: 11px;
    }

    .event-hero-file span {
      min-width: 0;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    .event-hero-file .ghost-link {
      width: auto;
      margin: 0;
    }

    .event-hero-remove {
      margin-top: 6px;
    }

    .admin-users-toolbar {
      display: grid;
      grid-template-columns: minmax(180px, 1fr) auto auto;
      align-items: center;
      gap: 8px;
      margin-bottom: 10px;
    }

    .admin-users-search {
      display: flex;
      align-items: center;
      gap: 8px;
      min-width: 0;
      border: 1px solid var(--line-mid);
      border-radius: var(--r-sm);
      padding: 0 10px;
      color: var(--muted);
    }

    .admin-users-search input {
      width: 100%;
      min-width: 0;
      height: 34px;
      border: 0;
      background: transparent;
      color: var(--ink);
      font-family: var(--F-sans);
      font-size: 12px;
      outline: none;
    }

    .admin-users-action,
    .admin-page-btn {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      gap: 6px;
      height: 34px;
      border: 1px solid var(--line-mid);
      border-radius: var(--r-pill);
      background: transparent;
      color: var(--ink);
      font-family: var(--F-sans);
      font-size: 9px;
      font-weight: 700;
      letter-spacing: .1em;
      text-transform: uppercase;
      cursor: pointer;
    }

    .admin-users-action {
      padding: 0 12px;
    }

    .admin-users-action.ghost {
      color: var(--muted);
    }

    .admin-users-action:hover:not(:disabled),
    .admin-page-btn:hover:not(:disabled) {
      background: var(--ink);
      color: #000;
    }

    .admin-users-action:disabled,
    .admin-page-btn:disabled {
      cursor: default;
      opacity: .45;
    }

    .admin-users-summary {
      font-family: var(--F-sans);
      font-size: 10px;
      color: var(--muted);
      margin: 8px 0 10px;
    }

    .admin-users-list {
      display: grid;
    }

    .admin-user-row {
      display: grid;
      grid-template-columns: minmax(0, 1fr) auto;
      align-items: center;
      gap: 12px;
      border-top: 1px solid var(--line);
      padding: 12px 0;
      font-family: var(--F-sans);
    }

    .admin-user-info {
      min-width: 0;
    }

    .admin-user-info strong {
      display: block;
      color: var(--ink);
      font-size: 13px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    .admin-user-info span,
    .admin-user-meta {
      display: block;
      margin-top: 3px;
      color: var(--muted);
      font-size: 11px;
    }

    .admin-user-role {
      display: grid;
      grid-template-columns: auto 132px;
      align-items: center;
      gap: 6px 8px;
      justify-content: end;
    }

    .admin-user-role label {
      color: var(--muted);
      font-family: var(--F-sans);
      font-size: 9px;
      font-weight: 700;
      letter-spacing: .1em;
      text-transform: uppercase;
    }

    .admin-user-role select {
      height: 32px;
      border: 1px solid var(--line-mid);
      border-radius: var(--r-sm);
      background: #050505;
      color: var(--ink);
      font-family: var(--F-sans);
      font-size: 11px;
      padding: 0 8px;
    }

    .admin-user-locked {
      grid-column: 2;
      color: var(--muted);
      font-family: var(--F-sans);
      font-size: 9px;
      letter-spacing: .08em;
      text-transform: uppercase;
    }

    .admin-users-pagination {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 12px;
      border-top: 1px solid var(--line);
      padding-top: 12px;
      margin-top: 2px;
      font-family: var(--F-sans);
      font-size: 11px;
      color: var(--muted);
    }

    .admin-page-btn {
      width: 34px;
      padding: 0;
      border-radius: 50%;
    }

    @media (max-width: 640px) {
      .admin-users-toolbar,
      .admin-user-row {
        grid-template-columns: 1fr;
      }

      .admin-users-action,
      .admin-user-role,
      .admin-user-role select {
        width: 100%;
      }

      .admin-user-role {
        grid-template-columns: 52px 1fr;
        justify-content: stretch;
      }
    }

    .admin-category-panel {
      border: 1px solid var(--line-mid);
      padding: 14px;
      margin-bottom: 18px;
    }

    .admin-category-title {
      font-family: var(--F-sans);
      font-size: 9px;
      font-weight: 700;
      letter-spacing: .16em;
      text-transform: uppercase;
      color: var(--muted);
      margin-bottom: 10px;
    }

    .admin-category-list {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
      gap: 8px;
    }

    .admin-category-row {
      display: grid;
      grid-template-columns: 12px minmax(64px, 1fr) 34px 92px;
      align-items: center;
      gap: 8px;
      min-height: 38px;
      border-top: 1px solid var(--line);
      padding-top: 8px;
      font-family: var(--F-sans);
    }

    .admin-category-dot {
      width: 10px;
      height: 10px;
      border-radius: 50%;
      box-shadow: 0 0 0 1px rgba(255, 255, 255, .4);
    }

    .admin-category-name {
      color: var(--ink);
      font-size: 11px;
      font-weight: 700;
      letter-spacing: .08em;
      text-transform: uppercase;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    .admin-category-picker {
      width: 34px;
      height: 28px;
      border: 1px solid var(--line-mid);
      border-radius: var(--r-sm);
      padding: 2px;
      background: transparent;
      cursor: pointer;
    }

    .admin-category-hex {
      width: 92px;
      height: 28px;
      border: 1px solid var(--line-mid);
      border-radius: var(--r-sm);
      padding: 0 8px;
      background: transparent;
      color: var(--ink);
      font-family: var(--F-sans);
      font-size: 11px;
      letter-spacing: .04em;
      text-transform: uppercase;
    }

    .admin-category-save {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      gap: 5px;
      grid-column: 2 / -1;
      justify-self: start;
      min-width: 70px;
      height: 28px;
      border: 1px solid var(--line-mid);
      border-radius: var(--r-pill);
      background: transparent;
      color: var(--ink);
      font-family: var(--F-sans);
      font-size: 9px;
      font-weight: 700;
      letter-spacing: .1em;
      text-transform: uppercase;
      cursor: pointer;
    }

    .admin-category-save:hover:not(:disabled) {
      background: var(--ink);
      color: #000;
    }

    .admin-category-save:disabled {
      cursor: default;
      opacity: .45;
    }

    .admin-category-error {
      grid-column: 2 / -1;
      color: #ffb6b9;
      font-family: var(--F-sans);
      font-size: 10px;
    }

    /* ── Admin vibes nomenclature panel ── */
    .admin-vibe-panel {
      border: 1px solid var(--line-mid);
      padding: 14px;
      margin-bottom: 18px;
    }

    .admin-vibe-title {
      font-family: var(--F-sans);
      font-size: 9px;
      font-weight: 700;
      letter-spacing: .16em;
      text-transform: uppercase;
      color: var(--muted);
      margin-bottom: 10px;
    }

    .admin-vibe-hint {
      margin: 0 0 14px;
      max-width: 640px;
      color: var(--muted);
      font-family: var(--F-sans);
      font-size: 11px;
      line-height: 1.5;
    }

    .admin-vibe-new {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)) auto;
      gap: 8px;
      align-items: stretch;
      margin-bottom: 16px;
    }

    .admin-vibe-new input,
    .admin-vibe-fields input {
      height: 30px;
      border: 1px solid var(--line-mid);
      border-radius: var(--r-sm);
      padding: 0 10px;
      background: transparent;
      color: var(--ink);
      font-family: var(--F-sans);
      font-size: 11px;
      letter-spacing: .04em;
      outline: none;
    }

    .admin-vibe-new input:focus,
    .admin-vibe-fields input:focus {
      border-color: var(--neon);
    }

    .admin-vibe-list {
      display: grid;
      gap: 12px;
    }

    .admin-vibe-row {
      display: grid;
      gap: 8px;
      border-top: 1px solid var(--line);
      padding-top: 10px;
    }

    .admin-vibe-fields {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
      gap: 8px;
    }

    .admin-vibe-fields label {
      display: grid;
      gap: 4px;
      font-family: var(--F-sans);
      font-size: 9px;
      font-weight: 700;
      letter-spacing: .12em;
      text-transform: uppercase;
      color: var(--muted);
    }

    .admin-vibe-actions {
      display: flex;
      align-items: center;
      gap: 8px;
      flex-wrap: wrap;
    }

    .admin-vibe-delete {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      gap: 5px;
      min-width: 82px;
      height: 28px;
      border: 1px solid var(--line-mid);
      border-radius: var(--r-pill);
      background: transparent;
      color: var(--muted);
      font-family: var(--F-sans);
      font-size: 9px;
      font-weight: 700;
      letter-spacing: .1em;
      text-transform: uppercase;
      cursor: pointer;
    }

    .admin-vibe-delete:hover:not(:disabled) {
      background: var(--ink);
      border-color: var(--ink);
      color: #000;
    }

    .admin-vibe-delete:disabled {
      cursor: default;
      opacity: .45;
    }

    .admin-vibe-row .admin-category-error {
      grid-column: auto;
    }

    .admin-row {
      display: flex;
      justify-content: space-between;
      align-items: center;
      gap: 14px;
      border: 1px solid var(--line-mid);
      margin-top: -1px;
      padding: 12px 14px;
      font-family: var(--F-sans);
      font-size: 13px;
    }

    .admin-row-info span {
      font-size: 11px;
      color: var(--muted);
    }

    .admin-status-badge {
      display: inline-flex;
      align-items: center;
      margin-left: 8px;
      border: 1px solid var(--line-mid);
      border-radius: var(--r-pill);
      padding: 2px 7px;
      color: var(--ink);
      font-size: 8px;
      font-weight: 700;
      letter-spacing: .1em;
      text-transform: uppercase;
      vertical-align: middle;
    }

    .admin-row-actions {
      display: flex;
      gap: 8px;
      flex-shrink: 0;
    }

    .admin-row-actions button {
      border: 1px solid var(--line-mid);
      background: transparent;
      color: var(--ink);
      font-family: var(--F-sans);
      font-size: 11px;
      letter-spacing: .08em;
      padding: 7px 12px;
      border-radius: var(--r-pill);
      cursor: pointer;
    }

    .admin-row-actions button:hover {
      background: var(--ink);
      color: #000;
    }

    .admin-row-actions button.rej:hover {
      background: #e5484d;
      border-color: #e5484d;
      color: #fff;
    }

    .admin-row-actions button.delete {
      border-color: rgba(229, 72, 77, .5);
      color: #ffb6b9;
    }

    .admin-row-actions button.delete:hover {
      background: #e5484d;
      border-color: #e5484d;
      color: #fff;
    }

    /* Ultra-minimal nav: text only, no pills */
    .tb-btn,
    .tb-btn.solid {
      border: none !important;
      background: transparent !important;
      color: var(--ink);
      padding: 8px 6px;
      letter-spacing: .14em;
      text-transform: uppercase;
    }

    .tb-btn:hover,
    .tb-btn.solid:hover,
    .tb-btn.solid {
      color: var(--neon);
      background: transparent !important;
    }

    .tb-search {
      border: none;
      border-bottom: 1px solid var(--line-mid);
      border-radius: 0;
      background: transparent;
      padding: 0 2px;
    }

    .tb-search:focus {
      border-bottom-color: var(--neon);
      outline: none;
    }

    /* grid/list switch */
    .view-toggle {
      display: flex;
      align-items: center;
      gap: 6px;
      margin: 14px 0 4px;
      font-family: var(--F-sans);
      font-size: 11px;
      letter-spacing: .14em;
      text-transform: uppercase;
      color: var(--muted);
    }

    .view-toggle button {
      border: none;
      background: none;
      font: inherit;
      letter-spacing: inherit;
      text-transform: inherit;
      color: var(--muted);
      cursor: pointer;
      padding: 2px 2px;
    }

    .view-toggle button:hover,
    .view-toggle button.active {
      color: var(--neon);
    }

    /* Traum-style program table */
    .trow {
      display: grid;
      grid-template-columns: 170px 1fr 110px 130px;
      gap: 0;
      align-items: stretch;
      padding: 0;
      border: 1px solid var(--line-mid);
      margin-top: -1px;
      font-family: var(--F-sans);
      font-size: 13px;
      cursor: pointer;
      transition: color .15s, border-color .15s, background .15s;
    }

    .trow > * {
      display: flex;
      align-items: center;
      padding: 15px 16px;
      min-width: 0;
    }

    .trow > *+* {
      border-left: 1px solid var(--line);
    }

    .trow:hover {
      background: rgba(255, 255, 255, .05);
    }

    .trow .tr-date {
      color: var(--muted);
      font-size: 11px;
      letter-spacing: .06em;
      line-height: 1.45;
      white-space: normal;
    }

    .trow .tr-title {
      color: var(--ink);
      font-weight: 500;
      min-width: 0;
    }

    .trow .tr-cat {
      color: var(--muted);
      font-size: 10px;
      letter-spacing: .14em;
      text-transform: uppercase;
      justify-content: flex-end;
    }

    .trow .tr-tix {
      color: var(--ink);
      font-size: 11px;
      letter-spacing: .08em;
      /* The word now comes from the shared events.tickets message ("Tickets"),
         which is capitalised for the detail button. The row keeps its original
         lowercase look without duplicating the string. */
      text-transform: lowercase;
      text-decoration: none;
      white-space: nowrap;
      justify-content: center;
    }

    .trow .tr-tix.dim {
      color: var(--muted);
    }

    .trow:hover,
    .trow:hover .tr-title,
    .trow:hover .tr-date,
    .trow:hover .tr-cat,
    .trow:hover .tr-tix {
      color: var(--neon);
      border-color: rgba(255, 255, 255, .5);
    }

    .trow:active .tr-title {
      color: var(--neon);
    }

    @media (max-width: 600px) {
      .trow {
        grid-template-columns: 1fr 96px;
        grid-template-rows: auto auto;
      }

      .trow > * {
        padding: 11px 12px;
      }

      .trow .tr-date {
        grid-row: 2;
        grid-column: 1;
        border-top: 1px solid var(--line);
        border-left: none;
      }

      .trow .tr-cat {
        display: none;
      }

      .trow .tr-tix {
        grid-row: 1 / 3;
        align-self: stretch;
      }
    }

    /* Display type: tighter, heavier */
    h1, h2, h3,
    .hero-word {
      letter-spacing: -.02em;
    }

/* ── Toasts ── */
    #toast-stack {
      position: fixed;
      bottom: 26px;
      left: 50%;
      transform: translateX(-50%);
      z-index: 100001;
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 8px;
      pointer-events: none;
      width: min(92vw, 480px);
    }

    .toast {
      background: var(--ink);
      color: var(--paper);
      font-family: var(--F-sans);
      font-size: 11px;
      font-weight: 600;
      letter-spacing: .08em;
      text-transform: uppercase;
      padding: 12px 20px;
      border: 1px solid var(--ink);
      max-width: 100%;
      text-align: center;
      opacity: 0;
      transform: translateY(10px);
      transition: opacity .35s cubic-bezier(.22, 1, .36, 1), transform .35s cubic-bezier(.22, 1, .36, 1);
    }

    .toast.show {
      opacity: 1;
      transform: translateY(0);
    }

    .toast.error {
      background: #3b1417;
      color: #ff9d95;
      border-color: rgba(255, 120, 110, .45);
    }

    @media (max-width:600px) {
      /* 72 is the tab bar plus the gap a toast wants above it, so it rises with the bar —
         including the safe area the bar now paints, or the message lands inside the strip
         the bar was grown to cover. */
      #toast-stack {
        bottom: calc(72px + env(safe-area-inset-bottom, 0px));
      }
    }

    /* ── Confirm modal ── */
    #confirm-overlay,
    .confirm-overlay {
      position: fixed;
      inset: 0;
      background: rgba(10, 10, 10, .55);
      z-index: 100000;
      display: none;
      align-items: center;
      justify-content: center;
      padding: 20px;
      backdrop-filter: blur(3px);
    }

    #confirm-overlay.open,
    .confirm-overlay.open {
      display: flex;
    }

    .confirm-box {
      background: var(--paper);
      border: 1px solid var(--ink);
      padding: 34px 34px 28px;
      max-width: 420px;
      width: 100%;
      text-align: center;
    }

    .confirm-box h3 {
      font-family: var(--F-condensed);
      font-size: 21px;
      font-weight: 600;
      letter-spacing: .04em;
      text-transform: uppercase;
      margin-bottom: 8px;
    }

    #confirm-event-name,
    .confirm-event-name {
      font-family: var(--F-serif);
      font-style: italic;
      font-size: 15px;
      color: var(--ink);
      margin-bottom: 10px;
    }

    .confirm-sub {
      font-family: var(--F-sans);
      font-size: 12.5px;
      line-height: 1.55;
      color: var(--muted);
      margin-bottom: 24px;
    }

    .confirm-actions {
      display: flex;
      gap: 10px;
      justify-content: center;
    }

    .confirm-actions button {
      height: 40px;
      padding: 0 22px;
      font-family: var(--F-sans);
      font-size: 10px;
      font-weight: 600;
      letter-spacing: .13em;
      text-transform: uppercase;
      cursor: pointer;
      transition: background .2s, color .2s;
    }

    .confirm-cancel {
      background: transparent;
      border: 1px solid var(--line-mid);
      color: var(--ink);
    }

    .confirm-cancel:hover {
      border-color: var(--neon);
    }

    .confirm-delete {
      background: #e5484d;
      border: 1px solid #e5484d;
      color: #fff;
    }

    .confirm-delete:hover {
      background: #b3261e;
      border-color: #b3261e;
    }

    .confirm-delete:disabled {
      opacity: .55;
      cursor: not-allowed;
    }

    /* ── My events rows ── */
    .mine-row {
      display: grid;
      grid-template-columns: 110px 1fr auto;
      align-items: center;
      border-bottom: 1px solid var(--line);
    }

    .mine-row:first-child {
      border-top: 1px solid var(--line);
    }

    .mine-date-col {
      padding: 22px 0;
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 5px;
      border-right: 1px solid var(--line);
      align-self: stretch;
      justify-content: center;
    }

    .mine-info {
      padding: 18px 24px;
      min-width: 0;
    }

    .mine-title {
      font-family: var(--F-display);
      font-size: 18px;
      font-weight: 500;
      line-height: 1.3;
      letter-spacing: -.01em;
      cursor: pointer;
    }

    .mine-title:hover {
      text-decoration: underline;
      text-underline-offset: 3px;
    }

    .mine-meta {
      font-family: var(--F-sans);
      font-size: 10px;
      color: var(--muted);
      letter-spacing: .12em;
      text-transform: uppercase;
      margin-top: 6px;
    }

    .mine-status-row {
      margin-top: 8px;
    }

    .mine-status {
      display: inline-flex;
      border: 1px solid var(--line-mid);
      border-radius: var(--r-pill);
      padding: 3px 8px;
      font-family: var(--F-sans);
      font-size: 8px;
      font-weight: 700;
      letter-spacing: .1em;
      text-transform: uppercase;
      color: var(--muted);
    }

    .mine-status-approved {
      color: var(--neon);
      border-color: var(--neon);
    }

    .mine-status-closed,
    .mine-status-rejected {
      color: #ffb6b9;
      border-color: rgba(229, 72, 77, .5);
    }

    .mine-rejection-message,
    .admin-rejection-message {
      margin-top: 10px;
      border-left: 3px solid #e5484d;
      padding: 8px 10px;
      color: var(--ink);
      background: color-mix(in srgb, #e5484d 8%, transparent);
      font-family: var(--F-sans);
      font-size: 11px;
      line-height: 1.5;
      white-space: pre-wrap;
      overflow-wrap: anywhere;
    }

    .mine-rejection-message strong {
      display: block;
      margin-bottom: 3px;
      color: #e5484d;
      font-size: 9px;
      text-transform: uppercase;
    }

    .mine-rejection-message p,
    .admin-rejection-message {
      margin-bottom: 0;
    }

    .mine-actions {
      padding: 0 24px;
      display: flex;
      gap: 8px;
    }

    .mine-delete {
	  display: inline-flex;
	  align-items: center;
	  gap: 6px;
      height: 34px;
      padding: 0 16px;
      background: transparent;
      border: 1px solid var(--line-mid);
      color: var(--ink);
      font-family: var(--F-sans);
      font-size: 9.5px;
      font-weight: 600;
      letter-spacing: .13em;
      text-transform: uppercase;
      cursor: pointer;
      transition: background .2s, color .2s, border-color .2s;
    }

    .admin-reject-dialog {
      width: min(520px, calc(100vw - 32px));
    }

    .admin-reject-dialog label {
      display: block;
      margin: 14px 0 6px;
      color: var(--muted);
      font-family: var(--F-sans);
      font-size: 9px;
      font-weight: 700;
      text-transform: uppercase;
    }

    .admin-reject-dialog textarea {
      width: 100%;
      min-height: 140px;
      resize: vertical;
      border: 1px solid var(--line-mid);
      background: var(--field);
      color: var(--ink);
      padding: 10px;
      font: 13px/1.5 var(--F-sans);
    }

    .mine-delete:hover {
      background: var(--neon);
      color: #000;
      border-color: var(--neon);
    }

    .mine-count {
      font-family: var(--F-sans);
      font-size: 9px;
      font-weight: 600;
      letter-spacing: .16em;
      text-transform: uppercase;
      color: var(--muted);
      margin-bottom: 18px;
    }

    @media (max-width:600px) {
      .mine-row {
        grid-template-columns: 84px 1fr;
      }

      .mine-actions {
        grid-column: 1 / -1;
        padding: 0 0 16px 84px;
      }

      .mine-info {
        padding: 16px 14px 8px 18px;
      }
    }

    /* ── Source chip (auto-imported events) ── */
    .src-chip {
      display: inline-flex;
      align-items: center;
      gap: 5px;
      font-family: var(--F-sans);
      font-size: 8.5px;
      font-weight: 600;
      letter-spacing: .14em;
      text-transform: uppercase;
      color: var(--muted);
      border: 1px solid var(--line);
      padding: 3px 8px;
      margin-top: 6px;
      text-decoration: none;
      transition: color .2s, border-color .2s;
    }

    a.src-chip:hover {
      color: var(--ink);
      border-color: var(--neon);
    }

    .src-dot {
      width: 5px;
      height: 5px;
      border-radius: 50%;
      background: currentColor;
      flex-shrink: 0;
    }

    /* ── Live location dot (pulses while tracking) ── */
    .user-dot {
      position: relative;
      width: 16px;
      height: 16px;
      background: #0a0a0a;
      border: 2.5px solid #fff;
      border-radius: 50%;
      box-shadow: 0 0 0 4px rgba(10, 10, 10, .25), 0 0 18px rgba(10, 10, 10, .45);
    }

    .user-dot-pulse {
      position: absolute;
      inset: -10px;
      border-radius: 50%;
      border: 1.5px solid rgba(10, 10, 10, .5);
      animation: userPulse 2s cubic-bezier(.22, 1, .36, 1) infinite;
      pointer-events: none;
    }

    @keyframes userPulse {
      0% { transform: scale(.4); opacity: .9; }
      70% { transform: scale(1.35); opacity: 0; }
      100% { transform: scale(1.35); opacity: 0; }
    }

    @media (prefers-reduced-motion: reduce) {
      .user-dot-pulse { animation: none; opacity: 0; }
    }

    #ctrl-locate.tracking {
      background: var(--neon) !important;
      color: #000 !important;
      border-color: var(--neon) !important;
    }

    #mobile-list-btn { display: none; }

    /* ── The map's sheet chrome: the floating list toggle, the sheet stack ──
       900px, not 600px: it belongs to the widths where the list is a sheet, which is
       the same line the sheet itself is drawn on at the end of this file. The button
       is the only way back to the list once an event is open, so it cannot exist at
       599px and be missing at 601px. */
    @media (max-width:900px) {
      #app.map-mode #mobile-list-btn {
        display: flex;
        align-items: center;
        justify-content: center;
        position: fixed;
        bottom: calc(74px + env(safe-area-inset-bottom, 0px));
        left: 50%;
        transform: translateX(-50%);
        z-index: 58;
        height: 46px;
        padding: 0 24px;
        background: var(--sheet-accent);
        color: #fff;
        border: 1px solid var(--sheet-accent);
        border-radius: 23px;
        font-family: var(--F-sans);
        font-size: 10px;
        font-weight: 600;
        letter-spacing: .13em;
        text-transform: uppercase;
        cursor: grab;
        touch-action: none;
        box-shadow: 0 6px 24px rgba(214, 0, 127, .35);
      }

      #mobile-list-btn::before {
        content: "";
        width: 26px;
        height: 3px;
        border-radius: 2px;
        background: rgba(255, 255, 255, .6);
        margin-right: 9px;
      }

      /* Bottom sheet and detail sheet never share the screen (MapView keeps one
         open at a time), but the detail still paints above the list for the moment
         the two cross over, so a closing sheet can never sit on top of the list. */
      #panel { z-index: 56; }
      #detail { z-index: 57; }

      /* Keep the locate control clear of the floating button, and in the pill shape
         the phone version has always had — the size lived in the phone block until it
         moved here with the rest of the sheet chrome. */
      #ctrl-locate {
        top: 12px;
        left: 50%;
        right: auto;
        bottom: auto;
        transform: translateX(-50%);
        width: auto;
        height: 44px;
        border-radius: 22px;
        padding: 0 14px;
        gap: 6px;
        z-index: 60;
        background: var(--neon);
        color: #000;
        border-color: var(--neon);
        box-shadow: 0 6px 24px rgba(0, 0, 0, .5);
      }

      /* 16px above the bottom edge of the map, which ends where the tab bar begins
         (see #map-area in app.css). The 74px this used to have was compensation for
         a map area that ran on behind the navbar, and once the map was shortened it
         pushed the stack over the floating list button instead. Below the sheets on
         purpose: when one is open it is the foreground. */
      #ctrl-zoom { bottom: 16px; right: 14px; z-index: 40; }
    }

@media (pointer:fine) {

      html.nx-on,
      html.nx-on * {
        cursor: none !important;
      }

      html.nx-on input,
      html.nx-on textarea,
      html.nx-on select,
      html.nx-on [contenteditable] {
        cursor: text !important;
      }

      #nx-dot,
      #nx-ring {
        position: fixed;
        top: 0;
        left: 0;
        border-radius: 50%;
        opacity: 0;
        pointer-events: none;
        z-index: 100000;
        mix-blend-mode: difference;
        will-change: transform;
      }

      #nx-dot {
        width: 6px;
        height: 6px;
        margin: -3px 0 0 -3px;
        background: #fff;
      }

      #nx-ring {
        width: 34px;
        height: 34px;
        margin: -17px 0 0 -17px;
        border: 1px solid #fff;
        transition: width .3s cubic-bezier(.22, 1, .36, 1), height .3s cubic-bezier(.22, 1, .36, 1), margin .3s cubic-bezier(.22, 1, .36, 1), opacity .3s;
      }

      #nx-ring.hover {
        width: 62px;
        height: 62px;
        margin: -31px 0 0 -31px;
      }

      #nx-ring.click {
        width: 24px;
        height: 24px;
        margin: -12px 0 0 -12px;
      }
    }

    .nx-mag {
      transition: transform .35s cubic-bezier(.22, 1, .36, 1), background .2s, color .2s;
    }

    .hero-circle-label {
      transition: letter-spacing .45s cubic-bezier(.22, 1, .36, 1);
    }

    .hero-circle:hover .hero-circle-label {
      letter-spacing: .18em;
    }

    .pin>div:first-child {
      overflow: hidden;
    }

    .pin>div:first-child>svg {
      transition: transform .6s cubic-bezier(.22, 1, .36, 1);
    }

    .pin:hover>div:first-child>svg {
      transform: scale(1.12);
    }

    .map-filter-toggle {
      display: inline-flex;
      align-items: center;
      gap: 7px;
      border: 0;
      background: transparent;
      color: var(--ink);
      font: inherit;
      padding: 0;
    }

    .map-filter-toggle span {
      font-family: var(--F-sans);
      font-size: 8px;
      font-weight: 700;
      letter-spacing: .18em;
      text-transform: uppercase;
    }

    .map-filter-chevron {
      display: none;
    }

    @media (max-width:600px) {
      .desktop-add-event {
        display: none !important;
      }

      /* #panel, #panel.dragging and .panel-drag-handle used to be here and moved to
         the sheet block at the end of this file, where the sheet line lives. */
      .panel-topbar-mobile {
        padding-bottom: 7px;
      }

      .map-filter-stack {
        padding: 7px 14px;
        gap: 7px;
      }

      .map-filter-toggle {
        min-height: 28px;
        cursor: pointer;
      }

      .map-filter-chevron {
        display: block;
        transition: transform .2s ease;
      }

      .filters-expanded .map-filter-chevron {
        transform: rotate(180deg);
      }

      .map-filter-stack:not(.filters-expanded) .map-filter-bar {
        display: none;
      }

      /* Two dropdowns to a line on a phone, where the line breaks where the next
         control no longer fits — never inside one. */
      .map-filter-dd {
        min-width: 136px;
      }

      .chip,
      .vchip {
        min-height: 26px;
        padding-top: 5px;
        padding-bottom: 5px;
      }

      .panel-count {
        padding: 9px 14px;
      }

      #map-events-list {
        display: flex;
        flex-direction: column;
        gap: 8px;
        padding: 8px 14px 16px;
        overscroll-behavior: contain;
        -webkit-overflow-scrolling: touch;
      }

      /* A row in this list is a flex item in a column, and `min-height` replaces the
         automatic minimum that a flex item would otherwise take from its own content.
         So a row whose vibes wrapped stayed 82px tall and painted the rest - 77px of
         it, measured - straight through its own border onto the row underneath. The
         row has to keep its content, and the tag line has to stop growing instead of
         the row. */
      .event-row {
        flex-shrink: 0;
        min-height: 82px;
        gap: 12px;
        padding: 13px 14px;
        border: 1px solid var(--line);
      }

      /* One line of a display title cut off at "GOLQMATA ZABRANENA M…" on a 360px
         sheet. Two lines fit the same row and say the whole thing. */
      .event-row-title {
        font-size: 15px;
        line-height: 1.28;
        white-space: normal;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
      }

      .event-row-meta {
        margin-top: 6px;
        line-height: 1.6;
      }

      /* One line of vibes, clipped at the row, rather than five stacked lines at 7.5px.
         The badges cannot shrink - a badge that squashes to fit is worse than one that
         is off-screen - and the detail sheet has the full set. */
      .event-row-tags {
        flex-wrap: nowrap;
        overflow: hidden;
        gap: 6px;
        margin-top: 9px;
      }

      .event-row-badge {
        flex-shrink: 0;
        font-size: 8.5px;
        letter-spacing: .12em;
      }

      /* The source chip is an inline-flex of label + code + arrow, and left to shrink it
         folded "чрез KRUG-D4YTKD" onto two lines, which made the one-line tag row 44px
         tall by itself. It keeps its width and gets clipped like the badges. */
      .event-row-tags .src-chip {
        flex-shrink: 0;
        white-space: nowrap;
      }

      #mobile-nav {
        justify-content: flex-start;
        overflow-x: auto;
        overflow-y: hidden;
        overscroll-behavior-inline: contain;
        scrollbar-width: none;
        -webkit-overflow-scrolling: touch;
      }

      #mobile-nav::-webkit-scrollbar {
        display: none;
      }

      #mobile-nav button {
        flex: 0 0 72px;
        min-width: 72px;
        padding: 0 5px;
      }

      #myevents-list,
      #myevents-saved-masonry,
      #saved-masonry,
      #tonight-list,
      #past-list {
        width: 100%;
        display: grid;
        grid-template-columns: minmax(0, 1fr);
        gap: 10px;
        border: 0;
      }

      .mine-row,
      .tonight-row,
      .past-row {
        width: 100%;
        min-width: 0;
        min-height: 112px;
        border: 1px solid var(--line);
      }

      .mine-row:first-child {
        border-top: 1px solid var(--line);
      }

      .mine-date-col {
        min-width: 0;
        padding: 16px 6px;
      }

      .mine-info,
      .tonight-info,
      .past-info {
        min-width: 0;
        overflow-wrap: anywhere;
      }

      .mine-actions {
        padding: 4px 12px 12px 84px;
        flex-wrap: wrap;
      }

      .mine-delete {
        min-height: 38px;
      }

      /* A card is a card at every width: picture across the top, copy under it,
         one per row. On a phone the feed used to collapse into a 76px thumbnail
         column with the title beside it, which cut a window into the photo and
         read as a broken table — and that column only ever matched the swatch
         <div>, so an event with a real hero image got the narrow column without
         any of the rules written for it. The same list was broken two ways. */
      .masonry,
      .saved-masonry,
      #saved-masonry,
      #myevents-saved-masonry {
        display: grid;
        grid-template-columns: minmax(0, 1fr);
        gap: 20px;
        border-top: 0;
      }

      .pin,
      #saved-masonry .pin,
      #myevents-saved-masonry .pin {
        display: block;
        width: 100%;
        min-height: 0;
        border: 1px solid var(--line);
        border-radius: var(--r-card);
        overflow: hidden;
        padding: 0 0 22px;
      }

      /* The 16:9 frame now comes from the base rules, so this list is only about
         sitting flush: on a single column the hero is the top edge of the card, not
         a rounded picture floating inside it. The !important stays because this
         list is the thing that outvoted the old inline height, and a card frame is
         cheap insurance next to a photo that decides its own height. */
      .pin>.pin-hero-image,
      .pin>div:first-child,
      #saved-masonry .pin-hero-image,
      #myevents-saved-masonry .pin-hero-image,
      #saved-masonry .pin>div:first-child,
      #myevents-saved-masonry .pin>div:first-child {
        width: 100% !important;
        height: auto !important;
        min-height: 0;
        aspect-ratio: 16 / 9;
        object-fit: cover;
        border-right: 0;
        border-radius: 0 !important;
      }

      /* The card's copy keeps one inset at every width: 16px here, 20px on a
         desktop. The selectors are scoped to `.pin` so they outvote app.css
         `.pin-rating` and the plain `.vibe-tags` rule above, both of which are
         written for other layouts and would otherwise win on order or class count. */
      .pin h3 {
        font-size: 17px;
        line-height: 1.28;
        margin: 16px 16px 0;
      }

      .pin p {
        margin: 9px 16px 0;
        line-height: 1.7;
      }

      .pin .vibe-tags {
        margin: 12px 16px 0;
      }

      .pin .pin-rating {
        margin: 10px 16px 0;
      }

      .pin .save-count {
        margin: 9px 16px 0;
      }

      #masonry .trow {
        width: 100%;
        margin: 0 0 10px;
      }
    }

    /* Sizes a thumb and an eye have to work with, all of it measured on the phone
       build first: the bottom bar ran 576px of items through a 390px strip with the
       scrollbar hidden, the top-bar icons were 34px squares, the view-mode toggles
       were 19px tall, a rating star was a 30px target, and every field a visitor
       types into sat under 16px — which makes iOS zoom the page in and leave it
       there. The compact type scale stays wherever text is only read; it stops at
       the edge of anything you aim at or type into. */
    @media (max-width:600px) {
      /* The bar shares its width instead of running off the right edge. The
         scroller stays as the fallback for a 320px phone, where seven items do not
         fit: there the last one is cut at the edge of the screen, which is the
         affordance the hidden scrollbar took away. Tracking comes down with the
         size so the longest label — Организирай — still fits whole. */
      #mobile-nav button {
        flex: 1 1 0;
        min-width: 52px;
        padding: 0 4px;
        font-size: 8px;
        letter-spacing: .06em;
      }

      .tb-search-icon-btn,
      #lang-btn {
        min-width: 44px;
        min-height: 44px;
      }

      .view-toggle button {
        min-height: 40px;
        padding: 0 10px;
      }

      .chip {
        display: inline-flex;
        align-items: center;
        min-height: 40px;
      }

      /* Five of these in a 351px box leave room for the gap they already have. */
      #rate-stars .rate-star {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 44px;
        min-height: 44px;
      }

      .rate-skip {
        min-height: 44px;
        padding: 0 14px;
      }

      /* Under 16px a phone browser zooms to the field on focus and does not undo
         it when the keyboard closes, so the rest of the page stays enlarged. The
         sign-in form's fields are handled in app.css, which loads after this file.
         A file input is deliberately left alone: it never takes a keyboard, and its
         11px caption is the "no file selected" label inside the button. */
      .fg input,
      .fg select,
      .fg textarea {
        font-size: 16px;
      }

      /* The city tabs are the primary way to narrow the feed on a phone and they
         were 25px tall — a thumb covers three of them at once. */
      .city-switch button {
        min-height: 40px;
      }

      /* The launch gate is the first screen and the one read at arm's length; its
         labels were 8 and 9px, sized for a desktop poster. */
      .gate-clock {
        font-size: 13px;
      }

      .gate-label {
        font-size: 12px;
      }

      .gc span {
        font-size: 11px;
      }
    }

    /* ── The map is two sheets, and one of them at a time ──────────────────────
       Below 900px the list is no longer a column beside the map (see the 900px block
       that takes it out of the row), so it rides the bottom edge as a sheet — and so
       does the event, on top of it. Both belong to that one width and are kept
       together here for the reason the split version was wrong: the list used to switch
       at 600px and the event at 699px, and the widths in between had an overlay window
       and a sheet on the screen at the same time, over each other, with the panel's
       toggle hidden at that width and the floating list button not yet drawn, so the
       visitor had two panels and no way to close either. */
    @media (max-width:900px) {
      #app.map-mode {
        padding-bottom: 0;
      }

      /* The map keeps what is left of the screen: below the top bar, above the tab
         bar. The sheets are fixed, so they ride over it instead of being carved out of
         it, which is what let the list have a height of its own. */
      #map-area {
        position: absolute;
        top: var(--top-h);
        bottom: 58px;
        left: 0;
        right: 0;
        height: auto;
        overflow: hidden;
      }

      #panel {
        position: fixed;
        top: auto;
        bottom: 58px;
        left: 0;
        right: 0;
        width: 100% !important;
        height: var(--mobile-panel-height, 46dvh);
        max-height: calc(100dvh - var(--top-h) - 58px);
        border-right: none;
        border-top: 1px solid var(--ink);
        border-radius: 8px 8px 0 0;
        transform: translateY(100%);
        transition: transform .35s cubic-bezier(.22, 1, .36, 1);
        box-shadow: 0 -8px 40px rgba(0, 0, 0, .1);
      }

      #panel.open-mobile {
        transform: translateY(0);
      }

      #panel.dragging {
        transition: none;
      }

      .panel-drag-handle {
        min-height: 30px;
        padding: 9px 0 8px;
      }

      .panel-drag-handle span {
        height: 4px;
      }

      /* The event sheet, driven by EventDetail.vue. It used to scroll as a whole,
         which dragged the grab handle off screen with it; now the handle is pinned and
         .detail-body is the scroller, so the sheet can be pulled down to a peek
         without losing the map.

         Its ceiling is 88% of the same space the sheet maths uses, and EventDetail.vue
         snaps to that number: the two are one decision, CSS owning how tall the sheet
         may be and script owning where a released sheet lands. It was 52vh — half the
         screen — which is where the complaint that a description does not fit came
         from. A short event is still a short sheet, because the sheet opens at
         `height: auto` under this ceiling rather than pinned to it. */
      #detail {
        position: fixed;
        top: auto;
        bottom: 58px;
        left: 0;
        right: 0;
        border-radius: var(--r-card) var(--r-card) 0 0;
        border-top: 1px solid var(--line-mid);
        max-height: calc((100dvh - var(--top-h) - 58px) * 0.88);
        /* 100% of its own height plus the tab bar it rests on top of. Translating by
           the sheet's own height was enough to leave a sheet alone — but when no event
           is open the sheet is empty and therefore only as tall as its grab handle, so
           110% of almost nothing slid it down by almost nothing: a 29px strip of handle
           sat painted over the tab bar on a map with no event open, which is a panel
           the visitor never asked for and cannot close. */
        transform: translateY(calc(100% + 58px));
        overflow: hidden;
        /* Height is set from script, so it belongs in the transition too — the snap
           after a drag and the keyboard toggle should land, not jump. */
        transition:
          transform 0.35s cubic-bezier(.22, 1, .36, 1),
          height 0.22s ease;
        box-shadow: 0 -14px 50px rgba(0, 0, 0, .55);
      }

      #detail.show {
        transform: translateY(0);
      }

      #detail.dragging {
        transition: none;
      }

      #detail .detail-hero-image {
        flex-shrink: 0;
        /* No height cap here any more. The cap used to be 22dvh with object-fit:
           cover, which cut even a correct 16:9 upload: at 390px wide the sheet is
           390px across, so the frame it wants is 219px tall and the cap was 186.
           The ratio in the base rule is the cap now, and it still leaves the words
           room at the half stop - 219 of a 381px sheet at rest. */
      }

      /* At a peek there is room for the picture or for the words, and the words
         are the reason the sheet is open. */
      #detail.collapsed .detail-hero-image {
        display: none;
      }

      /* The handle used to be a painted div. It is a button now, so it has to
         survive being one. */
      .detail-handle {
        appearance: none;
        -webkit-appearance: none;
        background: none;
        border: 0;
        padding: 0;
        color: inherit;
      }

      .detail-handle:focus-visible {
        outline: 2px solid var(--neon);
        outline-offset: 2px;
        border-radius: var(--r-sm);
      }

      .detail-body {
        overscroll-behavior: contain;
        -webkit-overflow-scrolling: touch;
      }
    }

    /* The phone band, where the tab bar actually exists. Everything above these rules is
       the 900px band, which on an iPad in Safari has the same 58px reservation but no bar to
       reserve it for and no home indicator to spend it on — so the safe area is added here
       and not there, and a tablet sheet is not floated 34px above the bottom by an inset it
       never asked for.

       Both sheets rest on the bar, so they move with it: `bottom` clears the whole bar
       including its inset, the ceiling loses the same amount, and the parked position
       translates by it — a sheet slid "fully away" that still leaves a lip over the safe
       area is a panel nobody opened and nobody can find the handle of. */
    @media (max-width:600px) {
      #panel {
        bottom: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px));
        max-height: calc(
          100dvh - var(--top-h) - env(safe-area-inset-top, 0px) - var(--nav-h) -
            env(safe-area-inset-bottom, 0px)
        );
      }

      #detail {
        bottom: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px));
        max-height: calc(
          (100dvh - var(--top-h) - env(safe-area-inset-top, 0px) - var(--nav-h) -
              env(safe-area-inset-bottom, 0px)) *
            0.88
        );
        transform: translateY(calc(100% + var(--nav-h) + env(safe-area-inset-bottom, 0px)));
      }
    }
