/* ── Note Composer ─────────────────────────────────────────────────────────
   A note-shaped composer: the card mirrors the posted note (media on top,
   author header, body text, place footer) but every section is a field. The
   pin stays fixed on screen while the map is dragged underneath it, so the
   map does the placing, not the pin.

   Used logged-out on the preview map today; the same component is meant to
   become the default new/edit note interface, so nothing here assumes the
   guest page — see note-composer.js for the mode/adapter seams. */

.nc-root { position: fixed; inset: 0; z-index: 3000; pointer-events: none;
           font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
.nc-root * { box-sizing: border-box; }
.nc-root.nc-hidden { display: none; }

/* ── Marker styles ─ a verbatim copy of templates/index.html's ──────────
   The composer pin and the posted note have to be the same object, so this
   block is the app's own marker CSS pasted in unchanged — indentation and
   comments included — rather than a second, paraphrased recipe. Keep it
   diff-identical: if index.html's block changes, re-paste this one. */
        /* ── Marker styles ────────────────────────────────────────────────────
           A note's marker is a shape the author picks, not one hard-coded disc.
           Every style paints inside the SAME 44x44 box, centred on the
           coordinate: Mapbox reads offsetWidth to place the element and the ghost
           clone sizes its pop ring from it, the four corner badges hang off the
           box corners, and the status badge and preview caption hang off its
           bottom edge. So the style changes what is painted inside the box and
           never the box itself — a boxless "glowing emoji" still has a stable
           44px tap target while its font is still loading.

           Colour arrives as custom properties on the root (--mkr-c plus its three
           channels, so a rule can compose any alpha without color-mix), never as
           cssText — a cssText write would wipe them and leave the pin unpainted.
           Re-tinting on a live-status change is then four setProperty calls
           whatever the style is.

           What a style may NOT do: pulse, or wear an outer ring or glow. Those
           are the map's existing vocabulary — orange pulse is "happening now",
           violet is boosted, amber is the locals countdown, a static coloured
           glow is "you haven't read this", a white-then-colour ring is a search
           match. A style that borrowed one would make the real signal unreadable. */
        .mkr:not(.mapboxgl-marker) { position:relative; }
        .mkr { box-sizing:border-box; width:var(--mkr-size, 44px); height:var(--mkr-size, 44px);
               display:flex; align-items:center; justify-content:center;
               border:0 solid transparent; border-radius:50%;
               background-color:transparent; cursor:pointer;
               /* knobs the shared marker chrome below reads */
               --mkr-ring-size:40px; --mkr-ring-dy:0px;
               --mkr-badge-inset:-5px; --mkr-badge-dy:0px; --mkr-badge-dyb:0px;
               --mkr-cap-dy:0px; }
        /* The glyph is always its own span: it survives the badge appends that a
           textContent write would wipe, it keeps .marker-preview from inheriting
           the pin's white text-shadow, and it lets a shape live in ::before
           underneath it. */
        .mkr-glyph { position:relative; z-index:1; display:block; line-height:1;
                     transform:translateY(var(--emoji-dy, 0.04em));
                     -webkit-user-select:none; user-select:none; }

        /* Disc — the default, and pixel-identical to the marker that existed
           before styles did (44px border-box + 2px border == the old 40px
           content-box + 2px border). */
        .mkr-circle { border-width:2px; border-color:#fff; background-color:var(--mkr-c, #3b82f6);
                      box-shadow:0 2px 8px rgba(0,0,0,0.3); }
        .mkr-circle .mkr-glyph { font-size:calc(var(--mkr-size, 44px) * 0.455); color:#fff;
                                 text-shadow:0 0 6px #fff, 0 0 10px #fff, 0 1px 3px rgba(0,0,0,0.3); }

        /* Glowing emoji — no disc at all; the glyph floats in a halo of the
           note's colour. The halo is a background-image and not filter:
           drop-shadow(): a filter makes a compositing layer per marker and a busy
           viewport has 150 of them (the same reason _styleMarker refuses to use
           one). text-shadow alone isn't enough either — behind a colour-bitmap
           emoji it is engine-dependent, so the gradient carries the halo and the
           text-shadow only carries the tight contact outline. That outline is
           white AND dark on purpose: one of the two always separates the glyph
           from the map, whether it is over beige streets, dark-v11 or satellite
           photography, with no per-basemap branch. */
        .mkr-glow { --mkr-ring-size:calc(var(--mkr-size, 44px) * 0.773);
                    background-image:radial-gradient(closest-side,
                        rgba(var(--mkr-cr,59),var(--mkr-cg,130),var(--mkr-cb,246),0.78) 0%,
                        rgba(var(--mkr-cr,59),var(--mkr-cg,130),var(--mkr-cb,246),0.46) 42%,
                        rgba(var(--mkr-cr,59),var(--mkr-cg,130),var(--mkr-cb,246),0.16) 64%,
                        rgba(var(--mkr-cr,59),var(--mkr-cg,130),var(--mkr-cb,246),0) 82%);
                    box-shadow:none; }
        .mkr-glow .mkr-glyph { font-size:calc(var(--mkr-size, 44px) * 0.591);
                    text-shadow:0 0 2px rgba(255,255,255,0.95), 0 1px 3px rgba(0,0,0,0.55),
                                0 0 6px rgba(var(--mkr-cr,59),var(--mkr-cg,130),var(--mkr-cb,246),0.95),
                                0 0 12px rgba(var(--mkr-cr,59),var(--mkr-cg,130),var(--mkr-cb,246),0.75); }

        /* Outline — the value inversion of the disc: a near-white chip with a
           thick coloured rim. Same silhouette, opposite lightness, which across a
           hundred pins separates them faster than any corner-radius change would. */
        .mkr-ring { border-width:3px; border-color:var(--mkr-c, #3b82f6); background-color:rgba(255,255,255,0.94);
                    box-shadow:0 2px 8px rgba(0,0,0,0.3), inset 0 0 0 1.5px rgba(255,255,255,0.95); }
        .mkr-ring .mkr-glyph { font-size:calc(var(--mkr-size, 44px) * 0.432); color:var(--mkr-c, #3b82f6);
                               text-shadow:0 1px 0 rgba(255,255,255,0.9); }

        /* Diamond — the one angular silhouette. The rotation is on ::before and
           never on the root: Mapbox owns the root's transform and rewrites it on
           every render. A 31px square turned 45 degrees has a 43.8px diagonal, so
           it still fits the box, and its inscribed circle is ~27px, which is what
           sizes the glyph. */
        .mkr-diamond { --mkr-ring-size:calc(var(--mkr-size, 44px) * 0.955);
                       --mkr-shape:calc(var(--mkr-size, 44px) * 0.727); }
        .mkr-diamond::before { content:''; position:absolute; left:50%; top:50%; box-sizing:border-box;
                    width:var(--mkr-shape); height:var(--mkr-shape);
                    margin:calc(var(--mkr-shape) / -2) 0 0 calc(var(--mkr-shape) / -2);
                    background:var(--mkr-c, #3b82f6); border:2px solid #fff; border-radius:4px;
                    transform:rotate(45deg); box-shadow:0 2px 8px rgba(0,0,0,0.3); }
        .mkr-diamond .mkr-glyph { font-size:calc(var(--mkr-size, 44px) * 0.386); color:#fff;
                    text-shadow:0 0 5px rgba(0,0,0,0.35), 0 1px 2px rgba(0,0,0,0.45); }

        /* Quiet dot — a small coloured dot inside the full 44px tap target, no
           glyph. For the author who posts three hundred notes (a trail, a route
           of stops) and for imported layers, where three hundred emoji discs are
           not a map. Size is the strongest at-a-glance difference there is, which
           is also why it is two fixed sizes and not a slider: an arbitrary size
           control is just a way to make your own notes shout over everyone's. */
        .mkr-dot { --mkr-ring-size:calc(var(--mkr-size, 44px) * 0.636);
                   --mkr-cap-dy:calc(var(--mkr-size, 44px) * -0.273);
                   --mkr-badge-inset:calc(var(--mkr-size, 44px) * 0.205);
                   --mkr-shape:calc(var(--mkr-size, 44px) * 0.455); }
        .mkr-dot::before { content:''; position:absolute; left:50%; top:50%; box-sizing:border-box;
                    width:var(--mkr-shape); height:var(--mkr-shape);
                    margin:calc(var(--mkr-shape) / -2) 0 0 calc(var(--mkr-shape) / -2); border-radius:50%;
                    background:var(--mkr-c, #3b82f6); border:2.5px solid #fff;
                    box-shadow:0 1px 5px rgba(0,0,0,0.45); }
        .mkr-dot .mkr-glyph { display:none; }

        /* Teardrop — the conventional map pin, tip on the coordinate. Rotating a
           28px square -45 degrees about its centre puts its square corner 19.8px
           below centre, so lifting the shape by that much lands the tip exactly on
           the point. It is the only style that isn't radially symmetric, which is
           the whole reason --mkr-ring-dy / --mkr-badge-dy / --mkr-cap-dy exist:
           its chrome has to ride up with the head. */
        .mkr-pin { --mkr-shape:calc(var(--mkr-size, 44px) * 0.727);
                   --mkr-lift:calc(var(--mkr-shape) * -0.7071);
                   --mkr-ring-size:calc(var(--mkr-size, 44px) * 0.773);
                   --mkr-ring-dy:var(--mkr-lift);
                   --mkr-cap-dy:calc(var(--mkr-size, 44px) * -0.455);
                   --mkr-badge-inset:calc(var(--mkr-size, 44px) * 0.023);
                   --mkr-badge-dy:var(--mkr-lift);
                   --mkr-badge-dyb:calc(var(--mkr-size, 44px) * 0.445); }
        .mkr-pin::before { content:''; position:absolute; left:50%; top:50%; box-sizing:border-box;
                    width:var(--mkr-shape); height:var(--mkr-shape);
                    margin:calc(var(--mkr-shape) / -2) 0 0 calc(var(--mkr-shape) / -2);
                    background:var(--mkr-c, #3b82f6); border:2px solid #fff;
                    border-radius:50% 50% 50% 4px;
                    transform:translateY(var(--mkr-lift)) rotate(-45deg);
                    box-shadow:0 3px 7px rgba(0,0,0,0.38); }
        .mkr-pin .mkr-glyph { font-size:calc(var(--mkr-size, 44px) * 0.341); color:#fff;
                    transform:translateY(calc(var(--mkr-lift) + var(--emoji-dy, 0.04em)));
                    text-shadow:0 1px 2px rgba(0,0,0,0.4); }

        /* Dark basemap. Only the two styles that lean on a light surface need it —
           everything else already carries both a light rim and a dark shadow.
           body.map-dark is set wherever the map style is switched. */
        body.map-dark .mkr-ring { background-color:rgba(17,24,39,0.9); }
        body.map-dark .mkr-ring .mkr-glyph { text-shadow:0 0 4px rgba(0,0,0,0.85); }
        body.map-dark .mkr-glow .mkr-glyph {
                    text-shadow:0 0 2px rgba(0,0,0,0.9),
                                0 0 7px rgba(var(--mkr-cr,59),var(--mkr-cg,130),var(--mkr-cb,246),1),
                                0 0 16px rgba(var(--mkr-cr,59),var(--mkr-cg,130),var(--mkr-cb,246),0.85); }
        body.map-dark .mkr-circle,
        body.map-dark .mkr-diamond::before,
        body.map-dark .mkr-dot::before { border-color:rgba(255,255,255,0.95); }
        /* A2 — HUD pin shell (guest composer; same tokens as index when hud.css is on). */
        .mkr.ll-pin.mkr-circle { border-color: var(--ll-brass, #fd9e02); }
        .mkr.ll-pin.mkr-ring { background-color: var(--ll-panel, rgba(12,14,20,0.78)); }
        .mkr.ll-pin.mkr-diamond::before,
        .mkr.ll-pin.mkr-pin::before,
        .mkr.ll-pin.mkr-dot::before { border-color: var(--ll-brass, #fd9e02); }
        @media (prefers-reduced-motion: no-preference) {
            .mkr::before { transition:background-color .18s ease, border-color .18s ease; }
        }

/* ── Centre pin — fixed on screen, map moves under it ── */
/* The bubble is a .mkr: the shape, the fill and the glyph's size all come from
   the marker styles above, so the pin being placed is drawn by exactly the rules
   that will draw the posted note. Everything here is what makes it a *composer*
   pin and nothing else — a width, a background or a border-radius would out-
   specify the .mkr-* classes and pin every style back to a green disc. */
.nc-pin { position: absolute; transform: translate(-50%, -100%); pointer-events: none;
          transition: transform .12s ease-out; will-change: transform; }
.nc-pin-bubble { --mkr-size: 46px; position: relative; padding: 0; line-height: 1; }
/* A drop shadow the map's markers don't need: this one floats over the note card
   as well as the map. Only the two styles with an edge to cast it — the boxless
   ones carry their own contact shadow and would just look smudged. */
.nc-pin-bubble.mkr-circle,
.nc-pin-bubble.mkr-ring { box-shadow: 0 4px 14px rgba(0,0,0,.28); }
.nc-pin-stem { width: 2px; height: 14px; margin: 0 auto; background: rgba(0,0,0,.28); }
.nc-pin-dot  { width: 10px; height: 10px; border-radius: 50%; margin: -1px auto 0;
               background: rgba(0,0,0,.22); }
.nc-root.nc-dragging .nc-pin { transform: translate(-50%, -110%); }

/* ── Place search (top) ── */
.nc-search { position: absolute; top: 66px; left: 50%; transform: translateX(-50%);
             width: min(560px, calc(100vw - 24px)); pointer-events: auto; }
.nc-search-row { display: flex; align-items: center; gap: 8px; background: #fff;
                 border-radius: 26px; padding: 6px 6px 6px 14px;
                 box-shadow: 0 4px 20px rgba(0,0,0,.16); }
.nc-search-row input { flex: 1; min-width: 0; border: none; outline: none;
                       font-size: 14px; color: #111; background: none; padding: 8px 0; }
.nc-search-x { border: none; background: #f3f4f6; color: #6b7280; width: 32px; height: 32px;
               border-radius: 50%; font-size: 15px; cursor: pointer; flex-shrink: 0; }
.nc-search-results { margin-top: 6px; background: #fff; border-radius: 14px; overflow: hidden;
                     box-shadow: 0 8px 26px rgba(0,0,0,.18); max-height: 44vh; overflow-y: auto; }
.nc-search-results:empty { display: none; }
.nc-sr-item { padding: 11px 14px; font-size: 13px; color: #374151; cursor: pointer;
              border-bottom: 1px solid #f3f4f6; }
.nc-sr-item:last-child { border-bottom: none; }
.nc-sr-item:hover { background: #f5f7ff; }
.nc-sr-name { font-weight: 600; color: #111; }
.nc-sr-sub  { font-size: 11.5px; color: #9ca3af; margin-top: 1px; }

/* ── The card ── */
/* Height is the user's to set: drag the grip to resize, tap it to toggle between
   a compact card (more map to place on) and the full form. */
.nc-card { position: absolute; bottom: var(--nc-card-bottom, 0px); left: 50%; transform: translateX(-50%);
           width: min(560px, 100vw); height: var(--nc-card-h, 62vh); max-height: 90vh;
           overflow-y: auto;
           -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
           background: #fff; border-radius: 20px 20px 0 0; pointer-events: auto;
           box-shadow: 0 -8px 40px rgba(0,0,0,.24);
           transition: height .22s cubic-bezier(0.4,0,0.2,1);
           padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px)); }
.nc-root.nc-resizing .nc-card { transition: none; }
.nc-root.nc-compact .nc-media { display: none; }
/* The grip is a real handle — a full-width grab strip around the visible pill */
.nc-grip { width: 100%; height: 22px; display: flex; align-items: center; justify-content: center;
           cursor: grab; touch-action: none; flex-shrink: 0; position: sticky; top: 0;
           background: #fff; z-index: 2; }
.nc-root.nc-resizing .nc-grip { cursor: grabbing; }
.nc-grip::before { content: ''; display: block; width: 40px; height: 4px;
                   border-radius: 2px; background: #e5e7eb; transition: background .15s; }
.nc-grip:hover::before { background: #cbd5e1; }

/* Media strip */
.nc-media { display: flex; gap: 8px; padding: 10px 14px 2px; overflow-x: auto; }
.nc-media-add { flex: 0 0 auto; width: 84px; height: 84px; border-radius: 12px;
                border: 1.5px dashed #d1d5db; background: #fafbff; color: #6b7280;
                font-size: 11px; font-weight: 600; cursor: pointer; display: flex;
                flex-direction: column; align-items: center; justify-content: center; gap: 4px;
                text-align: center; padding: 6px; line-height: 1.25; }
.nc-media-add span { font-size: 20px; }
.nc-media-add.nc-locked { cursor: pointer; background: #f9fafb; color: #9ca3af; }
.nc-thumb { position: relative; flex: 0 0 auto; width: 84px; height: 84px; border-radius: 12px;
            overflow: hidden; background: #eef2ff; }
.nc-thumb img, .nc-thumb video { width: 100%; height: 100%; object-fit: cover; display: block; }
.nc-thumb-x { position: absolute; top: 3px; right: 3px; width: 20px; height: 20px;
              border: none; border-radius: 50%; background: rgba(0,0,0,.55); color: #fff;
              font-size: 12px; line-height: 1; cursor: pointer; }
.nc-thumb-prog { position: absolute; inset: 0; background: rgba(255,255,255,.7);
                 display: flex; align-items: center; justify-content: center;
                 font-size: 11px; font-weight: 700; color: #4f46e5; }

/* Author header */
.nc-hdr { display: flex; align-items: flex-start; gap: 10px; padding: 10px 14px 6px; }
.nc-avatar { width: 34px; height: 34px; border-radius: 50%; background: #e0e7ff; color: #4338ca;
             display: flex; align-items: center; justify-content: center; font-size: 15px;
             font-weight: 700; flex-shrink: 0; overflow: hidden; }
.nc-avatar img { width: 100%; height: 100%; object-fit: cover; }
.nc-hdr-main { flex: 1; min-width: 0; }
.nc-name-row { display: flex; align-items: center; gap: 6px; }
.nc-name { flex: 1; min-width: 0; border: none; border-bottom: 1.5px dashed #d1d5db;
           outline: none; font-size: 14.5px; font-weight: 700; color: #1f2937;
           padding: 2px 0; background: none; }
.nc-name:focus { border-bottom-color: #667eea; }
.nc-name::placeholder { color: #9ca3af; font-weight: 600; }
.nc-privacy { flex-shrink: 0; font-size: 10.5px; font-weight: 700; color: #047857;
              background: #d1fae5; border: none; border-radius: 20px; padding: 4px 10px;
              cursor: pointer; font-family: inherit; white-space: nowrap; }
.nc-privacy:hover  { background: #a7f3d0; }
.nc-privacy[aria-expanded="true"] { box-shadow: 0 0 0 2px #6ee7b7; }
.nc-privacy.nc-priv-locals-on { background: #ccfbf1; color: #0f766e; }
.nc-id-line { font-size: 11.5px; color: #9ca3af; margin-top: 3px; min-height: 15px; }
.nc-id-line.nc-id-warn { color: #b45309; }
.nc-id-line.nc-id-ok   { color: #047857; }

/* Privacy panel — opened from the chip, inline so it scrolls with the card
   instead of floating over a form the keyboard is already crowding */
.nc-priv-menu { display: none; margin: 2px 14px 6px; padding: 8px; border-radius: 14px;
                background: #f9fafb; border: 1.5px solid #eef0f4; }
.nc-priv-menu.nc-on { display: block; }
.nc-priv-head { font-size: 10.5px; font-weight: 800; letter-spacing: .04em; color: #9ca3af;
                text-transform: uppercase; padding: 2px 4px 6px; }
.nc-priv-opt { display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
               padding: 8px 9px; border: 1.5px solid transparent; border-radius: 11px;
               background: #fff; cursor: pointer; font-family: inherit; margin-bottom: 5px; }
.nc-priv-opt:hover { border-color: #e0e7ff; }
.nc-priv-opt.nc-sel { border-color: #667eea; background: #f5f7ff; }
.nc-priv-ico { font-size: 16px; flex-shrink: 0; }
.nc-priv-txt { flex: 1; min-width: 0; display: block; }
.nc-priv-txt b { display: block; font-size: 13px; font-weight: 700; color: #1f2937; }
.nc-priv-txt i { display: block; font-size: 11px; font-style: normal; color: #9ca3af;
                 line-height: 1.35; margin-top: 1px; }
.nc-priv-tick { display: none; flex-shrink: 0; font-size: 13px; font-weight: 800; color: #667eea; }
.nc-priv-opt.nc-sel .nc-priv-tick { display: block; }
.nc-priv-lock { display: none; flex-shrink: 0; font-size: 10px; font-weight: 700; color: #b45309;
                background: #fffbeb; border-radius: 20px; padding: 3px 7px; white-space: nowrap; }
.nc-priv-opt.nc-locked { background: #f5f6f8; }
.nc-priv-opt.nc-locked .nc-priv-txt b { color: #9ca3af; }
.nc-priv-opt.nc-locked .nc-priv-lock { display: block; }
.nc-priv-opt.nc-locked .nc-priv-tick { display: none; }
.nc-priv-locals { display: flex; align-items: center; gap: 9px; padding: 8px 9px; cursor: pointer;
                  border-radius: 11px; background: #fff; border: 1.5px solid transparent; }
.nc-priv-locals input { width: 17px; height: 17px; flex-shrink: 0; accent-color: #0d9488;
                        cursor: pointer; }
.nc-priv-locals.nc-sel { border-color: #5eead4; background: #f0fdfa; }
.nc-priv-note { display: none; font-size: 11px; line-height: 1.45; color: #6b7280;
                padding: 7px 5px 2px; }
.nc-priv-note.nc-on { display: block; }

/* Auth fields (appear once a username is typed) */
.nc-auth { display: none; padding: 0 14px 4px; }
.nc-auth.nc-on { display: block; }
.nc-auth input { width: 100%; padding: 9px 12px; margin-top: 6px; font-size: 13px;
                 border: 1.5px solid #e5e7eb; border-radius: 10px; outline: none; }
.nc-auth input:focus { border-color: #667eea; }
.nc-auth-err { font-size: 12px; color: #dc2626; margin-top: 6px; display: none; }
.nc-auth-err.nc-on { display: block; }

/* Body */
.nc-body { padding: 2px 14px 6px; }
.nc-text { width: 100%; min-height: 76px; border: none; outline: none; resize: none;
           font-size: 15px; line-height: 1.5; color: #1f2937; font-family: inherit;
           background: none; }
.nc-text::placeholder { color: #b6bcc7; }
.nc-count { text-align: right; font-size: 10.5px; color: #b6bcc7; }

/* Marker style row */
.nc-style { display: flex; align-items: center; gap: 6px; padding: 4px 14px 8px; flex-wrap: wrap; }
.nc-emoji-btn { width: 34px; height: 34px; border-radius: 10px; border: 1.5px solid #e5e7eb;
                background: #fff; font-size: 17px; cursor: pointer; flex-shrink: 0; }
.nc-swatch { width: 20px; height: 20px; border-radius: 50%; border: 2px solid #fff;
             box-shadow: 0 0 0 1.5px #e5e7eb; cursor: pointer; padding: 0; }
.nc-swatch.nc-sel { box-shadow: 0 0 0 2px #667eea; transform: scale(1.12); }
/* One tile per marker style, each drawn with the real marker CSS in the colour
   and emoji currently chosen — the picker is a row of the thing itself, not a
   row of names for it. It takes a line of its own below the swatches. */
.nc-style-tiles { flex: 1 0 100%; display: grid; gap: 6px; margin-top: 2px;
                  grid-template-columns: repeat(auto-fit, minmax(58px, 1fr)); }
.nc-style-tile { display: flex; flex-direction: column; align-items: center;
                 justify-content: flex-end; gap: 4px; padding: 7px 3px 5px;
                 border: 1.5px solid #e5e7eb; border-radius: 11px; background: #fff;
                 cursor: pointer; font-family: inherit; font-size: 10px; font-weight: 600;
                 color: #6b7280; -webkit-tap-highlight-color: transparent;
                 transition: border-color .12s, background .12s, color .12s; }
.nc-style-tile:active { transform: scale(0.96); }
.nc-style-tile.nc-sel { border-color: #667eea; background: #f5f7ff; color: #4338ca; }
/* The art is 32px tall whatever the style paints inside it, so the labels stay on
   one baseline; position:relative keeps the shapes that live in ::before anchored
   to their own tile instead of escaping to the card. */
.nc-style-art { height: 32px; display: flex; align-items: center; justify-content: center; }
.nc-style-art .mkr { position: relative; pointer-events: none; }
/* The teardrop's head is lifted a fixed 19.8px so its tip lands on the map
   coordinate. A tile has no coordinate, only a box, so drop it back into the
   middle of that box rather than let it climb out over the swatches above. */
.nc-style-art .mkr-pin { transform: translateY(7px); }   /* the teardrop's tip is its anchor; centre it in the tile instead */
.nc-style-lab { line-height: 1.15; text-align: center; }
.nc-emoji-grid { display: none; grid-template-columns: repeat(8, 1fr); gap: 4px;
                 padding: 8px 14px 10px; }
.nc-emoji-grid.nc-on { display: grid; }
.nc-emoji-grid button { border: none; background: #f9fafb; border-radius: 8px; padding: 6px 0;
                        font-size: 18px; cursor: pointer; }
.nc-emoji-grid button:hover { background: #eef2ff; }

/* Place footer */
.nc-foot { display: flex; align-items: center; gap: 8px; padding: 9px 14px;
           border-top: 1px solid #f3f4f6; font-size: 12px; color: #6b7280; }
.nc-foot-addr { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
                white-space: nowrap; }
.nc-foot-btn { flex-shrink: 0; border: 1.5px solid #e0e7ff; background: #f5f7ff; color: #4f46e5;
               border-radius: 20px; padding: 5px 11px; font-size: 11.5px; font-weight: 700;
               cursor: pointer; }

/* ── Make this a fundraiser ── */
.nc-fund { border-top: 1px solid #f3f4f6; }
.nc-fund-toggle { width: 100%; display: flex; align-items: center; justify-content: space-between;
                  gap: 8px; background: none; border: none; cursor: pointer; padding: 10px 14px;
                  font-size: 13px; font-weight: 700; color: #9d174d; }
.nc-fund-chev { transition: transform .15s ease; color: #db2777; font-size: 15px; }
.nc-fund.nc-fund-open .nc-fund-chev { transform: rotate(90deg); }
.nc-fund-body { display: none; flex-direction: column; gap: 8px; padding: 0 14px 12px; }
.nc-fund.nc-fund-open .nc-fund-body { display: flex; }
.nc-fund-story, .nc-fund-input, .nc-fund-cur {
    width: 100%; box-sizing: border-box; border: 1px solid #fbcfe8; border-radius: 8px;
    padding: 8px 10px; font-size: 13px; background: #fff; color: #111827; font-family: inherit; }
.nc-fund-story { line-height: 1.5; resize: vertical; }
.nc-fund-goal-row { display: flex; gap: 8px; }
.nc-fund-goal { flex: 1; }
.nc-fund-cur { width: auto; flex-shrink: 0; }
.nc-fund-note { font-size: 11px; color: #9d174d; line-height: 1.45; }
body.dark .nc-fund, body.dark .nc-foot { border-top-color: var(--nc-line); }
body.dark .nc-fund-toggle { color: #f9a8d4; }
body.dark .nc-fund-story, body.dark .nc-fund-input, body.dark .nc-fund-cur {
    background: var(--nc-surface-2); border-color: var(--nc-line-2); color: var(--nc-ink); }
body.dark .nc-fund-note { color: #f9a8d4; }

/* Actions — sticky so Post stays reachable however tall the card's fields grow */
.nc-actions { display: flex; gap: 8px; padding: 8px 14px 10px; position: sticky; bottom: 0;
              background: #fff; box-shadow: 0 -6px 12px -8px rgba(0,0,0,.25); }
.nc-btn { flex: 1; padding: 12px; border: none; border-radius: 14px; font-size: 14px;
          font-weight: 700; cursor: pointer; font-family: inherit; }
.nc-btn-cancel { flex: 0 0 auto; background: #f3f4f6; color: #4b5563; padding: 12px 18px; }
.nc-btn-post { background: linear-gradient(135deg,#667eea,#764ba2); color: #fff;
               box-shadow: 0 4px 14px rgba(102,126,234,.4); }
.nc-btn-post:disabled { opacity: .55; cursor: default; box-shadow: none; }
.nc-err { display: none; padding: 0 14px 8px; font-size: 12.5px; color: #dc2626; }
.nc-err.nc-on { display: block; }

/* Loops (🔄) — promised inline, then reported after the payout */
.nc-loops { color: #0f766e; font-weight: 800; white-space: nowrap; }
.nc-loops-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
                margin: 8px 14px 0; padding: 9px 12px; border-radius: 12px;
                background: #f0fdfa; border: 1.5px solid #99f6e4;
                font-size: 12.5px; font-weight: 700; color: #0f766e; }
.nc-loops-bal { margin-left: auto; font-weight: 600; color: #14b8a6; font-size: 11.5px; }
.nc-loops-row.nc-loops-miss { background: #fffbeb; border-color: #fde68a; color: #92400e;
                              font-weight: 600; line-height: 1.45; }
.nc-loops-row.nc-loops-miss .nc-loops { color: #92400e; }

/* ── Posted state — the fields firm up into the final post ── */
.nc-card.nc-posted .nc-name,
.nc-card.nc-posted .nc-text { border: none; pointer-events: none; }
.nc-posted-banner { display: flex; align-items: center; gap: 7px; padding: 10px 14px;
                    background: #ecfdf5; color: #047857; font-size: 12.5px; font-weight: 700;
                    border-bottom: 1px solid #d1fae5; }
.nc-posted-hint { margin: 8px 14px 0; padding: 9px 12px; border-radius: 12px;
                  background: #f0fdfa; border: 1.5px solid #99f6e4; color: #0f766e;
                  font-size: 12px; line-height: 1.45; font-weight: 600; }
.nc-posted-note { padding: 12px 14px 4px; }
.nc-posted-hdr { display: flex; align-items: center; gap: 9px; margin-bottom: 8px; }
.nc-posted-name { font-size: 14px; font-weight: 700; color: #1f2937; }
.nc-posted-text { font-size: 15px; line-height: 1.5; color: #1f2937; white-space: pre-wrap;
                  word-break: break-word; }
.nc-posted-foot { font-size: 11.5px; color: #9ca3af; padding: 8px 14px 0; }
.nc-posted-media { display: flex; gap: 8px; padding: 0 14px 10px; overflow-x: auto; }
.nc-posted-media img { width: 96px; height: 96px; border-radius: 12px; object-fit: cover; }

@media (max-width: 480px) {
    .nc-card { max-height: 58vh; }
    .nc-search { top: 62px; }
}

/* ══ Night mode ══════════════════════════════════════════════════════════════
   The composer is a white card over a dark basemap otherwise — and it is the
   one surface on the guest map you sit and read while typing, so it is the one
   that matters most. Hook and token names match templates/preview.html's block;
   the component is meant to become the signed-in editor too, and index.html
   already sets the same body.dark, so this will carry over unchanged.

   Everything below restates a rule above, by the same selector and in the same
   order, so the two halves can be diffed section by section. The marker block
   is deliberately absent: it paints a note's own colour and already carries
   both a light rim and a dark shadow, and index.html's body.map-dark rules are
   what adjust it — a second opinion here would put the two copies out of sync. */
.nc-root { --nc-surface:   #171b24;
           --nc-surface-2: #1e2430;
           --nc-surface-3: #262d3b;
           --nc-line:      #2b3240;
           --nc-line-2:    #3a4353;
           --nc-ink:       #e7e9ee;
           --nc-ink-2:     #a2acbd;
           --nc-ink-3:     #78829a;
           --nc-indigo:    #a5b4fc;
           --nc-teal:      #5eead4;
           --nc-amber:     #fcd34d; }

/* The card and its sections set no colour of their own in light mode — they
   inherit the page's black. On a dark ground that inheritance is the bug, so
   the root states the ink once and everything below it follows. */
body.dark .nc-root { color: var(--nc-ink); }

/* ── Place search ── */
body.dark .nc-search-row { background: var(--nc-surface); box-shadow: 0 4px 20px rgba(0,0,0,.5); }
body.dark .nc-search-row input { color: var(--nc-ink); }
body.dark .nc-search-row input::placeholder { color: var(--nc-ink-3); }
body.dark .nc-search-x { background: var(--nc-surface-3); color: var(--nc-ink-2); }
body.dark .nc-search-results { background: var(--nc-surface); box-shadow: 0 8px 26px rgba(0,0,0,.55); }
body.dark .nc-sr-item { color: var(--nc-ink); border-bottom-color: var(--nc-line); }
body.dark .nc-sr-item:hover { background: var(--nc-surface-3); }
body.dark .nc-sr-name { color: var(--nc-ink); }
body.dark .nc-sr-sub { color: var(--nc-ink-3); }

/* ── The card ── */
body.dark .nc-card { background: var(--nc-surface); box-shadow: 0 -8px 40px rgba(0,0,0,.6); }
body.dark .nc-grip { background: var(--nc-surface); }
body.dark .nc-grip::before { background: var(--nc-line-2); }
body.dark .nc-grip:hover::before { background: var(--nc-ink-3); }

/* Media strip */
body.dark .nc-media-add { border-color: var(--nc-line-2); background: var(--nc-surface-2); color: var(--nc-ink-2); }
body.dark .nc-media-add.nc-locked { background: var(--nc-surface-2); color: var(--nc-ink-3); }
body.dark .nc-thumb { background: var(--nc-surface-3); }
body.dark .nc-thumb-prog { background: rgba(15,18,25,.72); color: var(--nc-indigo); }

/* Author header */
body.dark .nc-avatar { background: #2a2f56; color: var(--nc-indigo); }
body.dark .nc-name { border-bottom-color: var(--nc-line-2); color: var(--nc-ink); }
body.dark .nc-name:focus { border-bottom-color: var(--nc-indigo); }
body.dark .nc-name::placeholder { color: var(--nc-ink-3); }
body.dark .nc-privacy { color: #6ee7b7; background: #06301f; }
body.dark .nc-privacy:hover { background: #0a4b30; }
body.dark .nc-privacy[aria-expanded="true"] { box-shadow: 0 0 0 2px #059669; }
body.dark .nc-privacy.nc-priv-locals-on { background: #0d2a28; color: var(--nc-teal); }
body.dark .nc-id-line { color: var(--nc-ink-3); }
body.dark .nc-id-line.nc-id-warn { color: var(--nc-amber); }
body.dark .nc-id-line.nc-id-ok { color: #6ee7b7; }

/* Privacy panel */
body.dark .nc-priv-menu { background: var(--nc-surface-2); border-color: var(--nc-line); }
body.dark .nc-priv-head { color: var(--nc-ink-3); }
body.dark .nc-priv-opt { background: var(--nc-surface); }
body.dark .nc-priv-opt:hover { border-color: #3a3f6b; }
body.dark .nc-priv-opt.nc-sel { border-color: var(--nc-indigo); background: #232744; }
body.dark .nc-priv-txt b { color: var(--nc-ink); }
body.dark .nc-priv-txt i { color: var(--nc-ink-3); }
body.dark .nc-priv-tick { color: var(--nc-indigo); }
body.dark .nc-priv-lock { color: var(--nc-amber); background: #2a1f06; }
body.dark .nc-priv-opt.nc-locked { background: var(--nc-surface-2); }
body.dark .nc-priv-opt.nc-locked .nc-priv-txt b { color: var(--nc-ink-3); }
body.dark .nc-priv-locals { background: var(--nc-surface); }
body.dark .nc-priv-locals.nc-sel { border-color: #14b8a6; background: #0d2a28; }
body.dark .nc-priv-note { color: var(--nc-ink-2); }

/* Auth fields */
body.dark .nc-auth input { border-color: var(--nc-line-2); background: var(--nc-surface-2); color: var(--nc-ink); }
body.dark .nc-auth input::placeholder { color: var(--nc-ink-3); }
body.dark .nc-auth input:focus { border-color: var(--nc-indigo); }
body.dark .nc-auth-err { color: #fca5a5; }

/* Body */
body.dark .nc-text { color: var(--nc-ink); }
body.dark .nc-text::placeholder { color: var(--nc-ink-3); }
body.dark .nc-count { color: var(--nc-ink-3); }

/* Marker style row */
body.dark .nc-emoji-btn { border-color: var(--nc-line-2); background: var(--nc-surface-2); color: var(--nc-ink); }
body.dark .nc-swatch { border-color: var(--nc-surface); box-shadow: 0 0 0 1.5px var(--nc-line-2); }
body.dark .nc-swatch.nc-sel { box-shadow: 0 0 0 2px var(--nc-indigo); }
body.dark .nc-style-tile { border-color: var(--nc-line-2); background: var(--nc-surface-2); color: var(--nc-ink-2); }
body.dark .nc-style-tile.nc-sel { border-color: var(--nc-indigo); background: #232744; color: var(--nc-indigo); }
body.dark .nc-emoji-grid button { background: var(--nc-surface-2); }
body.dark .nc-emoji-grid button:hover { background: var(--nc-surface-3); }

/* Place footer */
body.dark .nc-foot { border-top-color: var(--nc-line); color: var(--nc-ink-2); }
body.dark .nc-foot-btn { border-color: #3a3f6b; background: #232744; color: var(--nc-indigo); }

/* Actions */
body.dark .nc-actions { background: var(--nc-surface); box-shadow: 0 -6px 12px -8px rgba(0,0,0,.7); }
body.dark .nc-btn-cancel { background: var(--nc-surface-3); color: var(--nc-ink); }
body.dark .nc-err { color: #fca5a5; }

/* Loops */
body.dark .nc-loops { color: var(--nc-teal); }
body.dark .nc-loops-row { background: #0d2a28; border-color: #14504a; color: var(--nc-teal); }
body.dark .nc-loops-bal { color: #2dd4bf; }
body.dark .nc-loops-row.nc-loops-miss { background: #2a1f06; border-color: #78350f; color: var(--nc-amber); }
body.dark .nc-loops-row.nc-loops-miss .nc-loops { color: var(--nc-amber); }

/* ── Posted state ── */
body.dark .nc-posted-banner { background: #06301f; color: #6ee7b7; border-bottom-color: #0a4b30; }
body.dark .nc-posted-hint { background: #0d2a28; border-color: #14504a; color: var(--nc-teal); }
body.dark .nc-posted-name { color: var(--nc-ink); }
body.dark .nc-posted-text { color: var(--nc-ink); }
body.dark .nc-posted-foot { color: var(--nc-ink-3); }
