/* Step 2 of request access: the family profile dialog.
 *
 * Kept out of index.html's <style> because it is a self-contained component
 * that shares none of the hero's scroll machinery, and index.html is long.
 *
 * IT IS THE HERO'S CAPTURE PILL, SCALED UP. Same glass, same fonts, same
 * control treatments. The panel is the bar, the text fields are .bar__input,
 * and the send button is .bar__submit down to the shadow values. Nothing here
 * invents a second visual language for the same flow.
 *
 * Three rules carried over from the pill, all of them learned the hard way:
 *
 *  - Glass tints toward the OPPOSITE of the ground it sits on. The dialog
 *    floats over the darkened hero art, so its veil is WHITE. A tint of the
 *    ink would sink into that ground instead of lifting off it.
 *  - A control nested inside a glass panel gets NO fill, only an outline. Its
 *    background would stack on the panel's own veil and read as a separate
 *    solid object at any alpha. That is why every field below is transparent.
 *  - Edges carry the material: a light inset along the top, where light enters
 *    the near rim, and a dark inset along the bottom, the far wall of that rim
 *    in shadow.
 *
 * backdrop-filter is doing real work on the panel, unlike on the flat field:
 * the hero art sits behind it, so there is genuine content to bend. It is an
 * enhancement on top of the panel's own tint, never the thing holding the
 * dialog up. See the note on .pm__dialog.
 *
 * NO VIOLET ANYWHERE IN THIS FILE. The chrome is white and the deep near-black
 * the site uses for shadows. The only tokens referenced are --lo-rgb and
 * --black-rgb, so a theme flip cannot drag a purple surface back into it.
 */

.pm{
  position:fixed; inset:0; z-index:100;
  display:flex; align-items:center; justify-content:center;
  padding:24px 16px;
  /* The hero's own wash over the art, just heavier, so the dialog reads as a
     pane lit from the same scene rather than a box dropped on top of it.
     
     No backdrop-filter on the scrim. The panel inside it has one, and two
     stacked viewport-scale backdrop layers buy nothing over one: the scrim's
     job is to darken, which alpha does on its own and does everywhere. */
  background:rgba(var(--lo-rgb),.72);
  opacity:0; transition:opacity .24s ease;
  overflow-y:auto; overscroll-behavior:contain;
}
.pm.is-open{ opacity:1; }
.pm[hidden]{ display:none; }

.pm__dialog{
  position:relative; width:min(516px,100%);
  margin:auto;              /* centres it, and lets it scroll when it is taller than the viewport */
  border-radius:26px; padding:34px clamp(22px,4vw,36px) 28px;
  color:#fff;
  /* Tracking for the whole dialog, set once here and inherited. Safe in the
     shorthand's company: `font:` resets the font properties but never
     letter-spacing. The two display lines and the eyebrow tighten further on
     their own rules; everything else takes this. Form controls need it handed
     to them separately, just below. */
  letter-spacing:-.012em;
  /* .bar__form's recipe at panel scale: a white veil, a bright hairline, and
     the two insets that make it a rim rather than a box.

     The veil sits on a TINTED BASE rather than straight on the scrim, and the
     base is the load-bearing half. The blur is frosting: it is what turns the
     art behind into texture instead of a legible headline, and unlike the
     hero's pill -- where blurring a flat field just returns that field -- it
     is doing real work here, because there is art back there. But a viewport
     -scale backdrop layer is the first thing a compositor drops under load,
     and if it goes, the veil and the base together still have to keep the page
     behind from reading through. They are a pair: the veil was raised and the
     base lowered by the same amount, so the pane reads whiter while covering
     just as much. Thin BOTH and the dialog is one dropped layer away from
     having the hero's headline running across the middle of it.

     Worth knowing if you go looking: Claude's in-app browser has been seen to
     miss these layers in a SCREENSHOT while the live page rendered them
     correctly -- two captures a second apart, same CSS, one ghosted and one
     clean. But do not reach for that explanation first. The same symptom,
     persistently, meant this rule had been split in half by a stray brace and
     the panel genuinely had no background. Read the computed style off the
     element before blaming the capture. */
  background:linear-gradient(180deg, rgba(255,255,255,.32), rgba(255,255,255,.20)),
             rgba(var(--lo-rgb),.46);
  border:1px solid rgba(255,255,255,.30);
  -webkit-backdrop-filter:blur(20px) saturate(125%); backdrop-filter:blur(20px) saturate(125%);
  box-shadow:0 26px 64px rgba(var(--lo-rgb),.42),
             inset 0 1px 0 rgba(255,255,255,.55),
             inset 0 -1px 0 rgba(var(--lo-rgb),.18);
  transform:translateY(10px) scale(.985);
  transition:transform .24s ease;
}
.pm.is-open .pm__dialog{ transform:none; }

/* Form controls do NOT inherit the tracking above: the browser's own
   stylesheet pins letter-spacing to normal on input, button, select and
   textarea, and that UA declaration beats an inherited value. Without this the
   three fields and both buttons keep default tracking while every label around
   them tightens, which reads as the fields being set in a different face. */
.pm__dialog input,
.pm__dialog button,
.pm__dialog select,
.pm__dialog textarea{ letter-spacing:inherit; }

.pm__close{
  position:absolute; top:14px; right:14px;
  width:34px; height:34px; display:grid; place-items:center;
  border:0; border-radius:999px; background:none; cursor:pointer;
  color:#fff; opacity:.5; font:400 20px/1 Inter, system-ui, sans-serif;
  transition:opacity .15s ease, background .15s ease;
}
.pm__close:hover{ opacity:1; background:rgba(255,255,255,.12); }

/* ---- type -----------------------------------------------------------------
   Inter throughout, the same face the pill and the subline use. Weights stay
   at 500 and below: a heavy face on a glass panel reads cheap, which is the
   same note that set the blog's ceiling. */
.pm__title{
  margin:0 36px 10px 0;
  font:500 22px/1.25 Inter, system-ui, sans-serif; letter-spacing:-.03em; color:#fff;
}
.pm__note{
  margin:0; font:400 13.5px/1.6 Inter, system-ui, sans-serif;
  color:#fff; opacity:.72;
}
/* .62, not the .5 this started at. The pane was darkened-violet then and a
   half-strength white label held up on it; against the whiter veil it went
   faint. Same trap as the hero's submit label, which had to be brightened for
   the same reason when its ground changed. */
.pm__for{
  margin:22px 0 0; font:500 10.5px/1 Inter, system-ui, sans-serif;
  letter-spacing:.1em; text-transform:uppercase; color:#fff; opacity:.62;
}

.pm__field{ margin:14px 0 0; }
.pm__label{
  display:block; margin:0 0 7px;
  font:400 12.5px/1.4 Inter, system-ui, sans-serif; color:#fff; opacity:.72;
}
.pm__hint{ opacity:.62; }

/* No fill. It sits inside the panel's veil, so a background of its own would
   stack on that veil and stop reading as part of the same pane. */
.pm__input{
  width:100%; height:50px; padding:0 18px;
  /* Not the pill the hero's field is. At full width a pill's end caps eat the
     first and last centimetre of a line you are meant to read back, and there
     are four of these stacked. The buttons and the chips stay pills, which is
     the ordinary split: rounded rectangles to type into, pills to press. */
  border:1px solid rgba(255,255,255,.26); border-radius:12px;
  background:none; color:#fff;
  font:500 16px Inter, system-ui, sans-serif; outline:none;
  transition:border-color .16s ease, box-shadow .16s ease;
}
.pm__input::placeholder{ color:rgba(255,255,255,.56); font-weight:500; }
.pm__input:hover{ border-color:rgba(255,255,255,.4); }
.pm__input:focus-visible{
  border-color:rgba(255,255,255,.72);
  box-shadow:0 0 0 3px rgba(255,255,255,.16);
}
.pm__input[readonly]{
  border-color:rgba(255,255,255,.16); opacity:.66; cursor:default;
}
.pm__input[readonly]:hover{ border-color:rgba(255,255,255,.16); }

/* ---- checkbox groups -------------------------------------------------------
   A real fieldset and legend, so a screen reader reads the question before the
   options rather than four unexplained words in a row. */
.pm__group{ margin:18px 0 0; border:0; padding:0; min-width:0; }
.pm__group > legend{
  padding:0; margin:0 0 9px;
  font:400 12.5px/1.4 Inter, system-ui, sans-serif; color:#fff; opacity:.72;
}
.pm__opts{ display:flex; flex-wrap:wrap; gap:8px; }

/* The input keeps its place in the tab order and the accessibility tree: it is
   laid over the chip at zero opacity, not display:none'd, which would take it
   off a screen reader entirely. */
.pm__opt{ position:relative; }
.pm__opt input{
  position:absolute; inset:0; width:100%; height:100%;
  margin:0; opacity:0; cursor:pointer;
}
.pm__opt span{
  display:block; padding:10px 16px; border-radius:999px;
  border:1px solid rgba(255,255,255,.26); background:none;
  font:500 13.5px/1 Inter, system-ui, sans-serif; color:#fff;
  transition:background .16s ease, border-color .16s ease, color .16s ease, box-shadow .16s ease;
}
.pm__opt input:hover + span{ border-color:rgba(255,255,255,.46); }

/* A chosen chip lights up as the same bright pane as the send button, so
   "selected" and "the thing you press" speak one language. */
.pm__opt input:checked + span{
  background:rgba(255,255,255,.42); border-color:rgba(255,255,255,.6);
  -webkit-backdrop-filter:blur(14px) saturate(130%); backdrop-filter:blur(14px) saturate(130%);
  color:rgba(var(--black-rgb),.84);
  box-shadow:0 4px 12px rgba(var(--lo-rgb),.16), inset 0 1px 0 rgba(255,255,255,.9);
}
.pm__opt input:focus-visible + span{ box-shadow:0 0 0 3px rgba(255,255,255,.28); }

.pm__field.is-invalid .pm__input,
.pm__group.is-invalid .pm__opt input:not(:checked) + span{
  border-color:rgba(255,168,168,.8);
}

.pm__status{
  margin:16px 0 0; min-height:1.4em;
  font:400 12.5px/1.45 Inter, system-ui, sans-serif; color:#fff;
  opacity:0; transition:opacity .2s ease;
}
.pm__status.is-on{ opacity:.78; }
.pm__status.is-error{ color:#FFB4B4; opacity:1; }

.pm__actions{
  display:flex; align-items:center; justify-content:flex-end; gap:6px;
  margin:22px 0 0;
}

.pm__skip{
  height:50px; padding:0 18px; border:0; border-radius:999px;
  background:none; cursor:pointer;
  color:#fff; opacity:.72;
  font:500 15px Inter, system-ui, sans-serif;
  transition:opacity .16s ease, background .16s ease;
}
.pm__skip:hover{ opacity:1; background:rgba(255,255,255,.1); }

/* .bar__submit, verbatim: a brighter pane than the panel it sits in, its own
   drop shadow, and 3px of top padding because Inter's ascent runs taller than
   its descent and the word otherwise lands about 1.5px high. */
.pm__submit{
  height:50px; display:inline-flex; align-items:center; justify-content:center; line-height:1;
  padding:3px clamp(20px,3.2vw,30px) 0; border-radius:999px;
  background:rgba(255,255,255,.42); border:1px solid rgba(255,255,255,.6);
  -webkit-backdrop-filter:blur(14px) saturate(130%); backdrop-filter:blur(14px) saturate(130%);
  box-shadow:0 5px 14px rgba(var(--lo-rgb),.14),
             inset 0 1px 0 rgba(255,255,255,.9);
  /* The one number that departs from .bar__submit. On the hero that pane sits
     over darker art, so a .62 label clears contrast; over the dialog's lighter
     veil the same alpha measured around 3.8:1 and looked washed out. .84 puts
     it past 4.5:1 without touching the glass itself. */
  color:rgba(var(--black-rgb),.84);
  font:600 15px Inter, system-ui, sans-serif; text-transform:none;
  cursor:pointer; white-space:nowrap;
  transition:background .18s ease, transform .16s ease, box-shadow .18s ease;
}
.pm__submit:hover{
  background:rgba(255,255,255,.62); transform:translateY(-1px);
  box-shadow:0 9px 20px rgba(var(--lo-rgb),.18),
             inset 0 1px 0 rgba(255,255,255,.95);
}
.pm__submit:active{
  transform:translateY(0);
  box-shadow:0 3px 9px rgba(var(--lo-rgb),.14),
             inset 0 1px 0 rgba(255,255,255,.85);
}
.pm__skip:disabled, .pm__submit:disabled{ opacity:.55; cursor:default; }

.pm__skip:focus-visible, .pm__submit:focus-visible, .pm__close:focus-visible{
  outline:2px solid rgba(255,255,255,.85); outline-offset:2px;
}

/* ---- the state after a successful save ---- */
.pm__done{
  margin:0 0 10px; color:#fff;
  font:500 21px/1.35 Inter, system-ui, sans-serif; letter-spacing:-.03em;
}
.pm__done:focus{ outline:none; }
.pm__done-note{
  margin:0 0 24px; color:#fff; opacity:.72;
  font:400 13.5px/1.6 Inter, system-ui, sans-serif;
}

@media (max-width:560px){
  .pm{ padding:10px 12px; align-items:flex-start; }
  .pm__dialog{ padding:24px 20px 18px; border-radius:22px; }
  .pm__title{ font-size:20px; }
  .pm__actions{ flex-direction:column-reverse; align-items:stretch; gap:8px; }
  .pm__skip, .pm__submit{ width:100%; }
  /* The whole dialog fits a 375x812 screen with nothing to scroll for, which
     matters because the send button is the last thing in it. Tightened here
     rather than at every width: on a desktop the extra air is worth having. */
  .pm__field{ margin-top:12px; }
  .pm__for{ margin-top:18px; }
  .pm__group{ margin-top:15px; }
  .pm__status{ margin-top:12px; }
  .pm__actions{ margin-top:16px; }
}

/* The scroll beats deliberately ignore Reduce Motion, but a dialog is not a
   beat: there is nothing to follow here, so the setting is honoured. */
@media (prefers-reduced-motion:reduce){
  .pm, .pm__dialog{ transition:none; }
  .pm__dialog{ transform:none; }
}
