/* Minimal form primitives for the public General User pages (register/login/account).
   A separate, self-contained file (not panel.css) so it never risks cascading over the
   marketing landing page's own styles -- see layouts/member.ejs, which is the only place
   this is loaded. Falls back to hardcoded colors when landing.css's --tokens aren't present,
   so this file works even if loaded on its own. */

/* app-screen shell (mirrors the mobile app's own Edit Profile screen: pink top bar with a round
   back button, a circular avatar straddling the bar/body seam, white body below) so these public
   pages read as "the app on the web", not an admin-panel form. */
body { background: #fdf1f6; }

/* Site chrome around the app-card: on its own the card reads as a phone screen pasted onto a
   blank page, which is right on an actual phone but wrong on a desktop browser -- this bar plus
   the desktop hero pane (below) are what tell a wide viewport "you're still on the website". */
.member-shell { min-height: 100vh; display: flex; flex-direction: column; }
.member-sitebar { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 20px; background: #fff; border-bottom: var(--line, 3px solid #000); }
.member-brand { display: inline-flex; align-items: center; gap: 8px; font-weight: 900; font-size: 15px; text-decoration: none; color: var(--ink, #101828); }
.member-brand img { width: 26px; height: 26px; object-fit: contain; }
.member-sitebar-link { font-size: 13px; font-weight: 700; text-decoration: underline; color: var(--ink, #101828); }

.member-page { flex: 1; display: grid; place-items: center; padding: 24px 16px; min-height: 60vh; }
.member-hero { display: none; }
.member-card { width: min(420px, 100%); display: grid; gap: 0; padding: 0; background: #fff; border: var(--line, 3px solid #000); border-radius: 18px; box-shadow: var(--shadow, 4px 4px 0 #000); overflow: hidden; }

/* Desktop/tablet: same card, but set inside a real website layout -- a marketing/brand pane next
   to it, both capped and centered in the viewport, instead of one narrow card floating alone. */
@media (min-width: 900px) {
    .member-page { grid-template-columns: minmax(0, 1fr) minmax(0, 420px); align-items: center; gap: 56px; max-width: 1080px; margin: 0 auto; padding: 48px 32px; }
    .member-hero { display: grid; align-content: center; gap: 16px; text-align: left; color: #fff; background: var(--pink, #ff1493); background-image: radial-gradient(#ffffff40 1.5px, transparent 1.5px); background-size: 22px 22px; border: var(--line, 3px solid #000); border-radius: 24px; padding: 48px; box-shadow: var(--shadow, 4px 4px 0 #000); min-height: 420px; }
    .member-hero h2 { margin: 0; font-size: 34px; line-height: 1.15; }
    .member-hero p { margin: 0; max-width: 34ch; font-size: 15px; font-weight: 600; }
    .member-card { justify-self: center; }
    /* Register/Account carry many more fields than Login -- a wider card gives the row-pairing
       below (form-grid) real columns to work with instead of squeezing them into 420px. */
    .member-page-wide { grid-template-columns: minmax(0, 1fr) minmax(0, 640px); }
    .member-page-wide .member-card { width: min(640px, 100%); }
}

/* Pairs short fields (name, phone/city, DOB/profession) into a 2-3 column row instead of one
   long vertical stack -- more practical for a website form than the phone app's single-column
   list. .field-full and fieldsets always take the whole row; plain fields flow left-to-right and
   wrap on their own once the row runs out of space, so this degrades to one column on narrow
   screens (phones, and the 420px Login card) with no extra markup or media query needed. */
.form-grid { display: grid; gap: 16px 20px; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.form-grid > .field-full, .form-grid > fieldset.field, .form-grid > .form-section-label, .form-grid > .form-section-divider, .form-grid > .account-photo-row { grid-column: 1 / -1; }
.form-grid > .btn { grid-column: 1 / -1; margin-top: 4px; }

/* Breaks a long field list into labeled groups (Basic Info / About You / ...) -- change request:
   "a lot of input fields, looks messy" -- so the mobile single-column stack reads as a few short
   forms instead of one long wall of identical boxes. Chosen over a multi-step wizard for now: no
   extra JS/state, still one scroll, one submit. */
.form-section-label { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 12px; font-weight: 900; letter-spacing: 1px; text-transform: uppercase; color: var(--pink, #ff1493); }
.form-section-label::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--pink, #ff1493); flex: 0 0 auto; }
.form-section-divider { height: 2px; border: none; background: #f0d7e4; margin: 0; }

/* Account page only: current profile photo + a "Change photo" control. Sits above Basic info,
   inside the same .form-grid as everything else (grid-column: 1 / -1, same as .form-section-label)
   so it doesn't need its own layout rules beyond this row's own flex. */
.account-photo-row { display: flex; align-items: center; gap: 14px; }
.account-photo { width: 72px; height: 72px; flex: 0 0 auto; border-radius: 50%; overflow: hidden; background: var(--pink, #ff1493); border: var(--line, 3px solid #000); display: flex; align-items: center; justify-content: center; }
.account-photo img { width: 100%; height: 100%; object-fit: cover; }
.account-photo-initial { color: #fff; font-weight: 900; font-size: 26px; }
.account-photo-edit { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 800; color: var(--pink, #ff1493); cursor: pointer; }
.account-photo-edit .icon { width: 18px; height: 18px; }
.account-photo-edit .account-photo-input { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

.member-topbar { display: flex; align-items: center; gap: 12px; padding: 16px 18px; background: var(--pink, #ff1493); border-bottom: var(--line, 3px solid #000); }
.member-back { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; width: 32px; height: 32px; border: var(--line, 3px solid #000); border-radius: 50%; background: #fff; color: #000; font-size: 16px; font-weight: 900; text-decoration: none; line-height: 1; }
.member-back:hover, .member-back:focus-visible { background: var(--yellow, #ffd700); outline: none; }
.member-topbar-title { flex: 1; margin: 0; padding-right: 32px; font-size: 16px; font-weight: 900; letter-spacing: .3px; color: #fff; text-align: center; text-transform: uppercase; }

.member-avatar { width: 72px; height: 72px; margin: -18px auto 0; display: grid; place-items: center; background: #fff; border: var(--line, 3px solid #000); border-radius: 50%; overflow: hidden; }
.member-avatar img { width: 58%; height: 58%; object-fit: contain; }

.member-body { display: grid; gap: 12px; padding: 18px 22px 26px; }
.member-body h1 { font-size: 22px; margin: 0 0 4px; }

.muted { color: #5b6472; font-weight: 400; }
.hint { color: #5b6472; font-weight: 400; font-size: 12px; }

.stack { display: grid; gap: 16px; }
.field, fieldset.field { display: grid; gap: 6px; border: 0; padding: 0; margin: 0; min-width: 0; }
.field > span, .field > legend { font-size: 13px; text-transform: uppercase; letter-spacing: .4px; padding: 0; }

.input { width: 100%; min-height: 46px; padding: 10px 16px; border: var(--line, 3px solid #000); border-radius: 999px; background: #fff; color: var(--ink, #101828); font: inherit; font-weight: 700; }
.input:focus { outline: 3px solid var(--pink, #ff1493); outline-offset: 0; }
select.input { appearance: none; -webkit-appearance: none; }

/* Show/hide eye icon inside a password field -- request: "user can see what they type". Both icons
   are always in the DOM (server-rendered, see register.ejs); the button's `active` class (toggled by
   public/js/password-toggle.js) swaps which one is visible, same convention as the Save/heart button
   (event-save.js) rather than swapping SVG markup from JS. The input gets right padding so typed text
   never runs under the icon. */
.password-field { position: relative; display: flex; }
.password-field .input { padding-right: 46px; }
.password-toggle { position: absolute; top: 0; right: 0; bottom: 0; width: 44px; display: flex; align-items: center; justify-content: center; background: none; border: 0; padding: 0; cursor: pointer; color: #6b7280; }
.password-toggle:focus-visible { outline: 3px solid var(--pink, #ff1493); outline-offset: -3px; border-radius: 8px; }
/* every other .icon usage in this codebase is sized per context (no global `.icon { width; height }`
   rule exists) -- missing this made the SVG render at its unstyled intrinsic size and effectively
   vanish inside the 44px button, caught via a real headless-browser screenshot, not just the source. */
.password-toggle .icon { width: 20px; height: 20px; }
.password-toggle-hide { display: none; }
.password-toggle.active .password-toggle-show { display: none; }
.password-toggle.active .password-toggle-hide { display: block; }

/* Date of birth: Day/Month/Year side by side instead of one native date input (change request --
   a native picker opens on today's month, so reaching a decades-old birth year took ~30 clicks).
   Fixed px widths (a first attempt) overflowed a narrow phone's card width, clipping the Year
   select off the right edge (bug report, screenshot) -- fr units instead always add up to exactly
   the row's own width, on any screen, so there is nothing left to overflow. Month gets a bit more
   of the row than Day/Year (long names like "September"), matching the earlier "shrink Month,
   grow Day/Year" request in relative terms without ever risking a fixed width again. */
.dob-row { display: grid; grid-template-columns: 1fr 1.3fr 1fr; gap: 8px; }
.dob-row .input { min-width: 0; width: 100%; padding-left: 10px; padding-right: 10px; }

/* Event enroll form: each participant is its own bordered block (same card look as .job-card/
   .event-card elsewhere) so multiple people's fields read as clearly separate groups instead of
   running together -- bug report: "below level and input field level padding is minimum" (fields
   inside a block, and the blocks themselves, had no gap/padding at all before this). */
#participants-list { display: grid; gap: 16px; }
.participant-row { display: grid; gap: 12px; padding: 16px; border: var(--line, 3px solid #000); border-radius: 16px; background: #fff; }
.participant-row h4 { margin: 0; font-size: 13px; text-transform: uppercase; letter-spacing: .4px; }
/* `.participant-row { display: grid }` has the SAME specificity as the browser's own built-in
   `[hidden] { display: none }` rule -- since this stylesheet loads after that default one, ours was
   winning, so event-enroll.js setting `row.hidden = true` stopped actually hiding anything (bug
   report: picking 1 or 2 participants still showed all 5 blocks). This rule's higher specificity
   (class + attribute) restores the hide. */
.participant-row[hidden] { display: none; }
/* single-tier events skip the dropdown (nothing to choose) and show the one price as plain text
   instead, matching the spacing of the `.field` it replaces. */
.field-static { display: grid; gap: 6px; margin: 0; }
.field-static span { font-size: 13px; font-weight: 700; }
.field-static strong { font-weight: 900; }
.enroll-total-price { margin: 0; padding: 12px 16px; border: var(--line, 3px solid #000); border-radius: 16px; background: #fff; font-weight: 900; text-align: center; }
/* Per-tier Min/Max live warnings (2026-10-07) -- e.g. "Adult: max 1 can be added." Same red/alert
   language as .alert.error, as a plain list (one line per violated tier) rather than one paragraph. */
.enroll-tier-warnings { margin: 0; padding: 12px 16px; border: 2px solid #000; border-radius: 12px; background: #ffd9dc; font-weight: 700; font-size: 14px; list-style: none; }
.enroll-tier-warnings li + li { margin-top: 6px; }

.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 8px 20px; border: var(--line, 3px solid #000); border-radius: 999px; background: #fff; color: #000; font-size: 13px; font-weight: 900; letter-spacing: .5px; text-transform: uppercase; cursor: pointer; box-shadow: var(--shadow, 4px 4px 0 #000); }
.btn.primary { background: var(--yellow, #ffd700); }
.btn.danger { background: #ff4d4f; color: #fff; }
.btn.block { width: 100%; }

/* Generic confirm popup (change request, 2026-10-07: member sidebar's Logout needed a "are you sure?"
   step) -- opt-in via [data-confirm-dialog] on a trigger button + a <dialog id> it points at (see
   public/js/confirm-dialog.js). Same markup/JS convention as the Panel's own .confirm-dialog
   (panel.css); kept as a separate rule here since this is a different stylesheet/design-token set
   (member app's --yellow/--line/--shadow vs the Panel's --desktop-* equivalents), not a duplicate. */
.confirm-dialog { width: min(360px, calc(100% - 32px)); padding: 24px; border: var(--line, 3px solid #000); border-radius: 18px; box-shadow: var(--shadow, 4px 4px 0 #000); background: #fff; color: var(--ink, #101828); }
.confirm-dialog::backdrop { background: #000b; }
.confirm-dialog-message { font-size: 15px; font-weight: 700; margin: 0 0 20px; }
.confirm-dialog-actions { display: flex; justify-content: flex-end; gap: 10px; }

.alert { padding: 12px 14px; border: 2px solid #000; border-radius: 12px; font-weight: 700; }
.alert.error { background: #ffd9dc; }
.alert.info { background: #cdefff; }

.checkbox { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 700; cursor: pointer; }
.checkbox input { width: 18px; height: 18px; accent-color: var(--pink, #ff1493); }

.back-link { font-size: 13px; text-decoration: underline; }

/* Preferred-location search box: a plain text input backed by a <datalist> and a hidden id field
   (see member-location-search.js). Works with no JS at all -- the browser's native datalist still
   filters as you type -- js only resolves the typed name back to an id before submit. */
.location-field input[type="text"] { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5'%3E%3Ccircle cx='10.5' cy='10.5' r='6.5'/%3E%3Cline x1='20' y1='20' x2='15.5' y2='15.5'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 16px center; background-size: 18px; padding-right: 44px; }

/* Membership package: a single row of cards the user scrolls horizontally instead of a checklist
   -- native radio semantics keep "only one" enforced with no JS. */
.package-scroll { display: flex; gap: 12px; overflow-x: auto; padding: 4px 4px 10px; scroll-snap-type: x proximity; }
.package-card { position: relative; flex: 0 0 auto; width: 168px; display: grid; gap: 6px; padding: 16px 16px 14px; border: var(--line, 3px solid #000); border-radius: 16px; background: #fff; cursor: pointer; scroll-snap-align: start; }
.package-card:has(.package-card-radio:checked) { background: var(--yellow, #ffd700); box-shadow: var(--shadow, 4px 4px 0 #000); }
.package-card-radio { position: absolute; top: 12px; right: 12px; width: 18px; height: 18px; margin: 0; accent-color: var(--pink, #ff1493); }
.package-card-name { padding-right: 22px; font-size: 15px; font-weight: 900; text-transform: uppercase; letter-spacing: .3px; }
.package-card-price { font-size: 13px; font-weight: 700; color: var(--ink, #101828); }
.package-card-tagline { font-size: 11px; font-weight: 600; color: #5b6472; line-height: 1.35; }
