/* Page-scoped rules migrated out of Setting[custom_css].
 *
 * This file is the Phase 3 half of a migration whose Phase 4 half is components.css:
 * the rules here are the ones that are genuinely about a page rather than about a
 * thing, and they are copied with their selectors and values intact rather than
 * being renamed into components that would have one call site each.
 *
 * It loads AFTER components.css and BEFORE application.css, and the operator's row
 * is still injected last, so while that row is live nothing here changes a pixel --
 * the row wins every tie. Cutover is when this file starts mattering.
 *
 * Every block carries the baseline line range it came from, so the parity harness's
 * findings can be traced back to a rule someone wrote rather than to a value someone
 * chose. Do not "tidy" a value here: several declarations in the row have never
 * painted, and the ones that have are load-bearing in ways the reconciliation
 * document spells out.
 *
 * THOSE LINE NUMBERS MOVE. They are absolute offsets into
 * design/custom-css-baseline.css, and nothing checks them. globals.css carries the
 * same numbers as machine-readable markers, which globals_css_parity_spec.rb compares
 * by position and which script/renumber_baseline_markers.rb exists to keep honest.
 * A citation in prose, like the ones below, has neither guard. The #login block was
 * cut out of the row on 2026-09-20, taking lines 646-790 with it, which puts every
 * prose citation into one of three cases: below 646 it still addresses the same
 * rule; above 790 it moved by -145; and one that pointed INTO 646-790 has no new
 * location at all. Those last are left exactly as written -- renumbering them would
 * invent a line -- and the prose around each is what says which rule it meant.
 *
 * DO NOT trust a sweep that matched `baseline:\d+`. This repo writes the same
 * kind of citation both ways: `baseline:1096`, and a bare `:1096`, `#vouchers:1534`
 * or `(:1628)` -- usually as the second and third halves of a sentence whose first
 * number carries the prefix. A regex anchored on the prefix skips all of those
 * silently, which is how the 2026-09-20 renumbering left stale pointers behind in
 * this file, components.css, globals.css and a spec while reporting itself
 * complete. Match the bare form too, and verify every number you write by reading
 * that line of the snapshot and checking it is the selector the prose names.
 * Cutting another block moves them again.
 * Docs under docs/ deliberately were NOT renumbered: they describe the snapshot as it
 * was when they were written, and rewriting them would falsify a record rather than
 * fix a pointer.
 */

/* ---------------------------------------------------------------------------
 * /vouchers -- baseline:1347-1425
 *
 * The button and the field are NOT here. They are .gp-btn and .gp-field__control
 * in components.css, applied alongside Bootstrap's .btn/.btn-primary and
 * .form-control in app/views/vouchers/index.html.erb.
 *
 * Two things in the original block are deliberately absent:
 *
 *   - `.btn-primary::after`, the glass rim. All three call sites are
 *     <input type="submit">, and a replaced element generates no pseudo-elements,
 *     so that rule has never painted. The parity harness reports its computed
 *     values as differences and flags them INERT for exactly this reason.
 *   - `#vouchers .form-control { color: var(--green) }`. text_field_tag emits
 *     id="code", so `#vouchers #code` outranks it and paints dk-green. The
 *     declaration is dead, like the non-breaking space in the .footer selector.
 *     Note that the `height` from that same block IS carried, at the bottom of this
 *     section -- one dead declaration in a rule does not make the rule dead.
 * ------------------------------------------------------------------------ */

/* The !important is carried across rather than cleaned up, and that is a decision.
 * Bootstrap's .mt-5 is `margin-top: 3rem !important`, so a normal declaration here
 * loses to it whatever the source order -- importance beats specificity. It also
 * has to stay a page-scoped selector rather than becoming a class on the markup:
 * the layout's flash wrapper carries .mt-5 too (app/views/layouts/application.html.erb,
 * the div wrapping `flash.each`), and that is shared by every page. */
#vouchers .d-flex.mt-5 {
  margin-top: 1rem !important;
}

#vouchers h1 {
  text-align: center;
}

/* The voucher artwork. Still the Squarespace CDN URL it has always been -- moving it
 * to a local asset is a real improvement and a separate change, because it is one
 * of four third-party requests the venue's wifi has to make during a show. The local
 * file already exists (Voucher+Mockup5.webp) and is not yet committed.
 *
 * The parity harness blocks this host in every mode, so the box's geometry is
 * compared and its paint is not. */
#vouchers h1::before {
  content: "";
  display: block;
  width: 300px;
  height: 200px;
  background-image: url("https://images.squarespace-cdn.com/content/543df105e4b01ddd00dd714c/ccf9e88f-9b2b-4863-92cc-cecb3c1fcda2/Voucher+Mockup5.png");
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}

#vouchers .text-center.mb-4 {
  padding-left: 30px;
  padding-right: 30px;
}

/* The only thing stacking the form above the button. Migrating the button and the
 * field without this renders an unstacked, uncentred page -- which is why the
 * reconciliation document lists it first among the rules that are easy to miss. */
#vouchers .row {
  flex-direction: column;
  align-items: center;
}

/* /vouchers is the only one of the four form pages that sets a size on the control.
 * #login, [id$="-edit"] and #referrals-new all set weight/colour/centring/radius and
 * no font-size, so this stays a page rule rather than moving into .gp-field__control
 * and silently shrinking the text on three pages that never asked for it. */
#vouchers #code {
  font-size: var(--gp-font-size-body);
}

/* The 42px control. This is the other half of the note above: it came out of
 * .gp-field__control because #vouchers is the only one of the four form pages that
 * sets a height at all, so carrying it in the component would have resized the
 * referral field to match a page it has nothing to do with. Written with the row's own
 * selector rather than .gp-field__control so that the cutover arithmetic is the same
 * one the row does today. */
#vouchers .form-control {
  height: var(--gp-control-height);
}

/* ---------------------------------------------------------------------------
 * /terms -- baseline:1546-1582
 *
 * Nothing is componentised here and no markup changes: this page has no button, no
 * field and no card. It is a Phase 3 verbatim migration and nothing else, which is
 * also what made it the page that forced the harness to be able to compare two
 * documents that are byte-identical. See docs/plans/referrals-and-terms-parity.md.
 *
 * Measured on the rendered page at 390px, not read out of the CSS: /terms renders NO
 * navbar. WelcomeController skips :check_if_logged_in for :terms, so @attendee is nil
 * whether or not anyone is signed in, and the layout guards the whole <nav> behind
 * `if @attendee`. The page shows the logged-out logo block instead. That is why the
 * only <h1> on this page is the title, and the only <ul>/<li> are inside the
 * ActionText body -- both assumptions these rules depend on, both asserted by
 * spec/requests/terms_parity_fixture_spec.rb rather than believed.
 * ------------------------------------------------------------------------ */

/* The page title lives in CSS. The view renders <h1>Terms</h1>; the h1 is collapsed
 * to nothing and the visible words are the CONTENT of its ::after. A screen reader
 * gets "Terms", because generated content is not reliably exposed -- so this is a
 * real defect and it is migrated AS IS. Moving the copy into the view changes the
 * accessible name, which is a change, and the freeze runs to 4 October. */
#terms h1:first-child {
  font-size: 0 !important;
  text-align: center;
}

#terms h1:first-child::after {
  content: "Terms of Service";
  font-size: calc(1.375rem + 1.5vw);
}

/* DEAD AS SHIPPED, and carried anyway. font-size loses to the `font-size: 0
 * !important` on the more specific h1:first-child (1,1,1 against 1,0,1), and
 * text-align is the same value that rule already sets. It would only come alive if
 * the page rendered a second <h1>, which -- with no navbar -- it cannot. Deleting it
 * is a decision about the design rather than a tidy-up, and it belongs after the run
 * with the rest of the dead rules. */
#terms h1 {
  font-size: calc(.8rem + 1.5vw);
  text-align: center;
}

/* 0.8rem = 12.8px, 1.2 = 15.36px line-height, measured. The 30px side padding sits
 * inside .container's own 12px, so the text column is 306px wide at 390px. */
#terms .trix-content {
  font-size: .8rem;
  line-height: 1.2;
  text-align: justify;
  padding-left: 30px;
  padding-right: 30px;
}

#terms .trix-content div:first-child {
  text-align: center;
}

#terms li {
  padding-top: .25rem;
  padding-bottom: .25rem;
}

#terms ul {
  padding-left: 1rem;
}

/* ---------------------------------------------------------------------------
 * /referrals/new -- baseline:1585-1670
 *
 * The third writing of the same form page as /vouchers and /attendees/:id/edit. The
 * button and the field are NOT here -- they are .gp-btn and .gp-field__control on the
 * markup in app/views/referrals/new.html.erb, alongside Bootstrap's own classes.
 *
 * `.btn-primary::after` is deliberately absent, as on /vouchers: the call site is
 * f.submit, which emits <input type="submit">, and a replaced element generates no
 * pseudo-element box. That rule has never painted.
 *
 * `.gp-form` is deliberately NOT used for the form width. .gp-form is
 * `min(var(--gp-dimension-form-width), 100% - 2rem)`, which resolves to 288px in this
 * wrapper against the 320px that ships -- a 32px narrowing at every viewport. A width
 * belongs to the layout, so the layout keeps it.
 *
 * Three of the rules below never render anything, measured on the page rather than
 * deduced. They are migrated verbatim because deleting a dead rule is a decision about
 * the design, not a tidy-up, and this migration is not allowed to make one.
 * ------------------------------------------------------------------------ */

#referrals-new .text-center.mb-4 {
  padding-left: 30px;
  padding-right: 30px;
}

/* 1.4rem = 22.4px, and this is the bare `.mt-5` rather than `.d-flex.mt-5` as on
 * /vouchers -- so it also catches the layout's flash wrapper and the .row.mt-5 that
 * holds the QR code. Narrowing the selector would move two things this page has
 * always positioned. */
#referrals-new .mt-5 {
  margin-top: 1.4rem !important;
}

#referrals-new .d-flex.justify-content-center.align-items-center.mb-5 {
  padding-left: 30px;
  padding-right: 30px;
}

/* DEAD AS SHIPPED: the 350px never paints. The form is a flex item inside the 380px
 * .mb-5 wrapper above, which has 30px of side padding, so its container's content box
 * is 320 and flex-shrink takes it there -- at every viewport, not only narrow ones.
 * Measured 320px at 390px wide. The margins DO render. */
#referrals-new form {
  width: 350px;
  margin-top: 30px;
  margin-bottom: 30px;
  margin-left: auto;
  margin-right: auto;
}

/* (0,1,1,1) -- this is what the label actually renders at. See .form-label below. */
#referrals-new .mb-3 label {
  font-size: 0.75rem;
}

/* Copied character for character, ordering trap included. `margin-bottom: 0
 * !important` is followed by a `margin: auto` SHORTHAND, which resets all four sides
 * -- and loses on the fourth, because importance beats source order. So this is
 * margin-bottom 0, margin auto on the other three. Tidying it changes the page.
 *
 * Its padding is dead: the longer .d-flex.justify-content-center.align-items-center.mb-5
 * selector above is (1,4,0) against this rule's (1,1,0), so 30px wins over 10px. */
#referrals-new .mb-5 {
  padding-right: 10px;
  padding-left: 10px;
  margin-bottom: 0 !important;
  width: 380px;
  margin: auto;
}

/* DEAD font-size, live everything else. `.mb-3 label` above is (1,1,1) against this
 * rule's (1,1,0), and bootstrap_form wraps every field in .mb-3, so the label ships at
 * 0.75rem and never at 0.6rem. text-transform and margin-bottom are uncontested and do
 * render -- which is why the label is uppercase at 12px rather than at 9.6px.
 * design/tokens.json records the same thing about font/size-label. */
#referrals-new .form-label {
  margin-bottom: 0rem !important;
  text-transform: uppercase;
  font-size: 0.6rem;
}

#referrals-new .mb-3 {
  text-align: center;
}

/* ---------------------------------------------------------------------------
 * [id$="_chuds_status"] -- baseline:150-307 (comment "Attendee status box" at :150)
 *
 * shared/_chuds_status.html.erb renders from two sites: welcome/index.html.erb:12
 * and attendees/edit.html.erb:6. This migration proves parity on `/` only; the
 * `/attendees/:id/edit` render of the same block is a later phase's job.
 *
 * The baseline nests this block under [id$="_chuds_status"] using CSS nesting;
 * pages.css is flat by convention, so every selector below is that scope plus the
 * nested selector as a descendant combinator. The one `&` in the source
 * (baseline:232, `.col-4:first-child { & h3 { ... } }`) is resolved the same way:
 * `&` there means "this selector, as an ancestor", so `& h3` is the descendant
 * selector `.col-4:first-child h3` -- split out below as its own rule rather than
 * staying nested, since flat CSS has no nesting to hold it in.
 * ------------------------------------------------------------------------ */

[id$="_chuds_status"] {
  margin-bottom: 2rem;
}

[id$="_chuds_status"] .mt-4 .card {
  border-style: none;
  background-color: #ededed !important;
  border-radius: 0;
}

[id$="_chuds_status"] .rounded {
  border-radius: 999px !important;
}

[id$="_chuds_status"] .p-3 {
  padding: 0.4rem !important;
  background: linear-gradient(
    111.92deg,
    rgba(220, 220, 220, 1) 20%,
    rgba(230, 230, 230, 1) 100%
  );
  border-radius: 8px;
  height: 60px;
  border-radius: 999px;
  --background: rgba(255, 255, 255, 0.65);
  border: 1px solid rgba(255, 255, 255, 0.75);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.06),
    0 2px 6px rgba(0, 0, 0, 0.08);
  backdrop-filter: blur(2px) saturate(180%);
}

[id$="_chuds_status"] .p-4 {
  padding: 0.3rem !important;
}

[id$="_chuds_status"] .text-muted.mb-1 {
  color: #6c6c6c;
  font-family: "IBM Plex Sans", sans-serif;
  font-style: normal;
  font-weight: 500;
  font-size: 9px;
}

[id$="_chuds_status"] .p-3 h3 {
  font-family: "IBM Plex Sans", sans-serif;
  font-style: normal;
  font-weight: 700;
  font-size: 24px;
  line-height: 29px;
  color: #1aaf11;
}

[id$="_chuds_status"] .p-3::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 2rem;
  backdrop-filter: blur(1px);
  box-shadow: inset -10px -8px 0px -11px rgba(255, 255, 255, 1),
    inset 0px -9px 0px -8px rgba(255, 255, 255, 1);
  opacity: 0.6;
  z-index: -1;
  filter: blur(1px) drop-shadow(10px 4px 6px black) brightness(115%);
}

[id$="_chuds_status"] .col-4 {
  padding-left: 6px;
  padding-right: 0px;
  width: 36%;
}

[id$="_chuds_status"] .col-4:last-child {
  width: 32%;
}

[id$="_chuds_status"] .col-4:first-child {
  padding-left: 0px;
  width: 30%;
}

[id$="_chuds_status"] .col-4:first-child h3 {
  font-family: "IBM Plex Sans", sans-serif;
  font-style: normal;
  font-weight: 700;
  font-size: 13px;
  line-height: 13px;
  padding: 0 8px;
}

[id$="_chuds_status"] .progress {
  height: 0.4rem !important;
  border-radius: 1rem;
  background-color: #cbcbcb;
  margin-top: 15px;
  width: 300px;
}

[id$="_chuds_status"] .progress-bar {
  background-color: var(--green);
}

[id$="_chuds_status"] .mt-2.fw-bold {
  font-family: "IBM Plex Sans", sans-serif;
  font-style: normal;
  font-weight: 700;
  font-size: 12px;
  line-height: 14px;
  color: #6c6c6c;
  margin-bottom: 0;
}

[id$="_chuds_status"] .mt-2.fw-bold::before {
  content: "Next Level: ";
  font-weight: 400;
}

[id$="_chuds_status"] .row {
  justify-content: space-between;
  margin: 0 15px 0 15px;
}

[id$="_chuds_status"] .mt-4:last-child {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
}

[id$="_chuds_status"] .card {
  border-radius: 16px;
  margin: 10px;
  background: rgba(255, 255, 255, 0.65);
  border: 1px solid rgba(255, 255, 255, 0.75);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.06),
    0 2px 6px rgba(0, 0, 0, 0.08);
  backdrop-filter: blur(2px) saturate(180%);
}

[id$="_chuds_status"] .card::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 16px;
  backdrop-filter: blur(1px);
  box-shadow: inset -10px -8px 0px -11px rgba(255, 255, 255, 1),
    inset 0px -9px 0px -8px rgba(255, 255, 255, 1);
  opacity: 0.6;
  z-index: -1;
  filter: blur(1px) drop-shadow(10px 4px 6px black) brightness(115%);
}

/* ---------------------------------------------------------------------------
 * #welcome-index + [id$="-edit"] -- baseline:30-135 (shared, comment
 * "Home Page" at :30), :1450-1452, :1454-1539 (comment "Edit Info Page" at
 * :1448), :1541-1543
 *
 * These two body ids share ONE selector list in the row for the whole
 * :30-135 block (baseline:31, "#welcome-index, [id$=\"-edit\"]" opening one
 * shared block), so neither could migrate without the other -- moving only
 * one would leave the unmoved half of a comma-joined list free to drift from
 * its twin.
 *
 * Flattened here as ONE comma-joined rule per declaration group, both scopes
 * named, exactly as the row has it -- not two copies. `#welcome-index .a,
 * [id$="-edit"] .a` is one rule that cannot drift into two; PARITY_PAGE=
 * welcome-index and PARITY_PAGE=attendees-edit each strip their own half out
 * of the row and strip_page_rules keeps the other (the partial-list case its
 * self-test already pins).
 *
 * :30-135's own nesting goes two levels deep in one place (#welcome-text
 * wraps #CompanyTriangle) and has one nested comma list of its own
 * (.modal-body, .modal-content) -- both resolved the same way as a plain
 * nested selector: no leading combinator means "descendant of everything
 * above", and a nested comma list is the cross product with what came
 * before it. So `.modal-body, .modal-content` under
 * `#welcome-index, [id$="-edit"]` becomes four selectors below, not two, and
 * `.modal-body` / `.modal-content` each appear TWICE -- once from that
 * combined rule, once again as their own standalone rule further down,
 * because that is what the row actually has.
 *
 * baseline:310-311, an empty `[id$="-edit"]` rule right after this block, is
 * a no-op -- no declarations to carry -- and is DROPPED rather than moved: an
 * empty rule changes no comparison this migration runs.
 *
 * baseline:1466-1468 nests `[id$="_chuds_status"].row.text-center` inside
 * `h1::after` -- a pseudo-element generates no box an element can descend
 * from, so this is dead by construction, the same shape as the /terms `h1`
 * rule above. Moved AS IS: fixing a dead rule is a visual change and the
 * freeze runs to 4 October.
 *
 * baseline:1541-1543, `[id$="-edit"] [id$="_chuds_status"]`, is the rule
 * Phase A's chuds-status migration could not reach: scoped_to? only matches
 * the LEFTMOST compound, so a `[id$="_chuds_status"]` in descendant position
 * is invisible to a `[id$="_chuds_status"]`-scoped migration. Moving it here
 * closes that cutover-coverage hole.
 *
 * The modal rules below (the "Show Ready Popup" `.modal.show .modal-dialog`,
 * `.bg-success`, and every `.modal`/`.modal-dialog`/`.modal-body`/
 * `.modal-content` rule) are migrated verbatim, but the parity harness
 * cannot exercise most of them: application.html.erb only renders that
 * markup behind `params[:new_login]`, and even then Bootstrap needs its own
 * JavaScript to add `.modal.show` -- the harness serves none. See
 * design/parity/welcome-index/reference/manifest.json for exactly which
 * rules that leaves uncovered, and why `.bg-success` is not one of them.
 * ------------------------------------------------------------------------ */

#welcome-index #welcome-text, [id$="-edit"] #welcome-text {
  padding-left: 30px;
  padding-right: 30px;
}

#welcome-index #welcome-text #CompanyTriangle, [id$="-edit"] #welcome-text #CompanyTriangle {
  width: 150px;
  margin-bottom: 1rem;
}

#welcome-index img.img-fluid, [id$="-edit"] img.img-fluid {
  padding-left: 30px;
  padding-right: 30px;
  margin-bottom: 1rem;
  margin-top: 1rem;
}

#welcome-index .pb-5, [id$="-edit"] .pb-5 {
  padding-bottom: .5rem !important;
}

#welcome-index .mt-5, [id$="-edit"] .mt-5 {
  margin-top: 0 !important;
}

#welcome-index .row.text-center, [id$="-edit"] .row.text-center {
  padding-left: 0px;
  padding-right: 0px;
}

#welcome-index .text-center, [id$="-edit"] .text-center {
  padding-left: 0px;
  padding-right: 0px;
}

/* Show Ready Popup */
#welcome-index .modal.show .modal-dialog, [id$="-edit"] .modal.show .modal-dialog {
  --margin-top: 50%;
}

#welcome-index .bg-success, [id$="-edit"] .bg-success {
  background-color: var(--green) !important;
}

#welcome-index .modal-body, #welcome-index .modal-content,
[id$="-edit"] .modal-body, [id$="-edit"] .modal-content {
  border-radius: 2em;
}

#welcome-index .btn-close.m-2, [id$="-edit"] .btn-close.m-2 {
  margin: 1rem !important;
}

#welcome-index .modal-body h3, [id$="-edit"] .modal-body h3 {
  font-size: calc(1rem + 0.6vw);
}

#welcome-index .modal-dialog, [id$="-edit"] .modal-dialog {
  display: flex;
  justify-content: center; /* Centers items horizontally */
  align-items: center;
  height: 100%;
}

#welcome-index .modal, [id$="-edit"] .modal {
  height: 80%;
}

#welcome-index .modal-body, [id$="-edit"] .modal-body {
  position: relative;
  backdrop-filter: blur(2px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.8);
  border-radius: 2rem;
  box-shadow: 0 8px 32px rgba(31, 38, 135, 0.2),
    inset 0 4px 20px rgba(255, 255, 255, 0.3);
  width: 350px;
  margin: auto;
}

#welcome-index .modal-content, [id$="-edit"] .modal-content {
  border-style: none;
  background-color: transparent;
}

#welcome-index .modal-body::after, [id$="-edit"] .modal-body::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 2rem;
  backdrop-filter: blur(1px);
  box-shadow: inset -10px -8px 0px -11px rgba(255, 255, 255, 1),
    inset 0px -9px 0px -8px rgba(255, 255, 255, 1);
  opacity: 0.6;
  z-index: -1;
  filter: blur(1px) drop-shadow(10px 4px 6px black) brightness(115%);
}

/* Edit Info Page -- baseline:1450-1452, own top-level rule, no flattening
 * needed: it was never part of the shared list. */
[id$="-edit"] .col-12.col-sm-8.mx-auto.pt-5 {
  padding-top: 0 !important;
}

[id$="-edit"] .row.justify-content-center {
  margin: 0;
}

/* The page title lives in CSS, same trick as /terms above: the view renders
 * <h1>Edit Your Info</h1>, the h1 is collapsed to nothing, and the visible
 * words are the CONTENT of its ::after. Migrated as is. */
[id$="-edit"] h1 {
  font-size: 0 !important;
}

[id$="-edit"] h1::after {
  content: "Your Info";
  font-size: calc(1.375rem + 1.5vw);
}

/* Dead by construction: h1::after is a pseudo-element and generates no box
 * an element can descend from, so nothing can ever match this selector.
 * Moved AS IS -- fixing a dead rule is a visual change and the freeze runs
 * to 4 October. */
[id$="-edit"] h1::after [id$="_chuds_status"].row.text-center {
  padding-top: 10px;
}

[id$="-edit"] form {
  width: 350px;
  margin-top: 30px;
  margin-bottom: 30px;
  margin-left: auto;
  margin-right: auto;
}

[id$="-edit"] .mb-3 label {
  font-size: 0.75rem;
  /* text-transform: uppercase; */
}

[id$="-edit"] .form-control {
  font-weight: 800;
  text-align: center;
  color: var(--dk-green);
  border-radius: 5rem;
}

[id$="-edit"] .mb-5 {
  padding-right: 10px;
  padding-left: 10px;
  margin-bottom: 0 !important;
  width: 380px;
  margin: auto;
}

[id$="-edit"] .form-label {
  margin-bottom: 0rem !important;
  text-transform: uppercase;
  font-size: 0.6rem;
}

[id$="-edit"] .btn-primary {
  background-color: #1aaf13 !important;
  width: 150px;
  height: 42px !important;
  position: relative;
  backdrop-filter: blur(2px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.8);
  border-radius: 2rem;
  box-shadow: 0 8px 32px rgba(31, 38, 135, 0.2),
    inset 0 4px 20px rgba(255, 255, 255, 0.3);
  font-weight: 400;
  line-height: 1.5;
  padding: 0.25rem 0.5rem;
  font-size: 0.875rem;
}

[id$="-edit"] .btn-primary::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 2rem;
  backdrop-filter: blur(1px);
  box-shadow: inset -10px -8px 0px -11px rgba(255, 255, 255, 1),
    inset 0px -9px 0px -8px rgba(255, 255, 255, 1);
  opacity: 0.6;
  z-index: -1;
  filter: blur(1px) drop-shadow(10px 4px 6px black) brightness(115%);
}

/* Closes Phase A's cutover-coverage hole -- see the header note above. */
[id$="-edit"] [id$="_chuds_status"] {
  margin-bottom: 0 !important;
}

/* ---------------------------------------------------------------------------
 * /login -- baseline:647-789
 *
 * The last of the four form pages, and the only one whose markup was REWRITTEN
 * rather than reclassed (c8ee64b). That matters here more than anywhere else,
 * because most of the #login block is positional: the block addresses its page
 * through .mb-3:nth-child(n), .w-100 and .btn-lg, and the rewrite moved every one
 * of those onto a different element. Each rule below therefore says which element
 * it paints TODAY, measured on design/parity/login/migrated.html, not which one it
 * was written for.
 *
 * NOT here, and each for its own reason:
 *
 *   - :649-652, the background image. That is .gp-sky on the <body>
 *     (components.css), which is where a page background belongs and which is
 *     already applied by the layout. The row's URL is the old 9x16 cloud PNG and
 *     .gp-sky's is the new pair of jpgs -- an accepted visual change, not a
 *     parity failure.
 *   - :664, `form.mb-3:nth-child(4)`. There is no <form class="mb-3"> on this page
 *     and never was; the red background it declares has never painted.
 *   - :679-705, `.btn-lg` and its `::after` gloss. Two separate deaths. The button
 *     is now `<button class="gp-btn gp-btn--block">` and carries no .btn-lg at all,
 *     so the whole rule selects nothing; and the ::after could never have painted
 *     anyway, because the call site it was written for was `f.submit`, an
 *     <input type="submit">, and a replaced element generates no pseudo-elements.
 *     That is the same finding as #vouchers .btn-primary::after above. Porting the
 *     gloss onto the new real <button> would be adding a visual nobody has seen,
 *     not migrating one -- so the button is .gp-btn and nothing else.
 *   - :707 AND :712-715, `.form-text { display: none }`. LIVE today: the
 *     redeclaration at :721 sets font-style only and never puts display back, which
 *     is why no help text renders on this page in production. Deliberately dropped:
 *     the rewritten form shows help text and inline errors, and carrying this
 *     forward would hide the help text under every field. The errors themselves
 *     were already routed around it -- they render into .gp-field__msg, a class the
 *     row has never heard of -- but the help text was collateral and is being given
 *     back on purpose.
 *   - :721, `.form-text { font-style: italic }`. Never seen, for the reason above,
 *     and see the note on .gp-field__hint in components.css. Porting it would make
 *     italic help text a new visual on the one page that is about to start showing
 *     help text.
 *   - :741-748, `.mt-5.nth-child(1)` and `.mt-5.nth-child(2)`. `.nth-child(1)` is a
 *     literal class name, not a pseudo-class. Nothing has ever carried it.
 *   - :774-776, `.w-50 { width: 90% }`. Nothing on this page carries .w-50: the
 *     wrapper is .w-md-50, which is not a Bootstrap class either.
 *   - :767-768, `.mt-3 { margin-bottom: 1rem }`. Nothing on this page carries
 *     .mt-3 -- the help-text wrapper is .my-3.
 *   - :785-788, already commented out in the row.
 *   - The four custom properties the block declares and nothing reads --
 *     `--border-color`, `--margin-top` (twice) and `--background`. They are typos
 *     for real properties, they resolve to nothing, and re-typing `red` into the
 *     repo would be putting an untokenised colour into a stylesheet to no effect.
 *
 * MERGE NOTE, 2026-09-20. main shipped its own port of this block in PR #203
 * (6a13984..3dafe0b) while this branch was open: a byte-verbatim copy of
 * baseline:647-789, nested, with the row's literals. It was correct for main, where
 * `markup_change: false` and the page still renders `f.submit`, `.btn-lg` and four
 * `.mb-3` children. It is NOT correct here, because c8ee64b rewrote the markup, and a
 * verbatim copy cannot see that: every positional selector in it now addresses a
 * different element, `#login { background-image: ... }` at (1,0,0) would outrank the
 * layout's `.gp-sky` on the same <body>, and `.form-text { display: none }` would hide
 * the help text this branch added -- which is moot as of 2026-09-21: that help text is
 * cut, so there is no .form-text left on the page for it to hide. Kept as a record of
 * why the exclusion was needed. None of those three are visible to the parity
 * harness -- `derive_current` only strips class NAMES, so `current` and `cutover`
 * render the same DOM and a verbatim block is trivially green in both. So main's
 * FINDINGS are kept, all of them, and they are what the exclusions above cite; main's
 * verbatim TEXT is not. See docs/plans/login-parity.md for the measurements.
 * ------------------------------------------------------------------------ */

#login form {
  width: var(--gp-dimension-form-width);
  /* The gap between the Join Show button and the footer (Corey, 2026-09-21:
   * the button sat too close). Was a bare 30px. It is margin on the form, so
   * it meets the footer's own `mt-auto` -- which on a short page is what
   * pushes the footer to the bottom anyway, so this only paints where the
   * content is tall enough to reach it, which on a phone it is. */
  margin-bottom: var(--gp-dimension-form-gap-bottom);
}

/* (1,1,1) against .form-label's (1,1,0) below -- the label renders at 0.75rem and
 * never at the 0.6rem that rule asks for. Same arithmetic as #referrals-new. */
#login .mb-3 label {
  font-size: var(--gp-font-size-small);
}

/* The terms checkbox, and the one place on the attendee surface where an author
 * !important beats an inline style: the markup carries style="transform: scale(2.0)",
 * and an important declaration in an author sheet outranks a normal inline one. The
 * box ships at 1.5, not at 2. Tidying the !important away would grow it by a third. */
#login input[type="checkbox"] {
  accent-color: var(--gp-action-primary);
  transform: scale(1.5) !important;
}

/* Three elements, not one: the form wrapper in welcome/login.html.erb, the layout's
 * flash slot, and the logged-out logo block. Narrowing the selector would move two
 * of them. */
#login .mt-5 {
  margin-top: 1rem !important;
}

/* Closing the logo-to-form gap (Corey, 2026-09-21: "less space between logo and
 * that so the whole form fits without scrolling").
 *
 * Measured at 390x844 before this: documentHeight 883 against an 844 viewport, and
 * a real iPhone loses roughly another 90px to Safari's chrome, so the usable height
 * is nearer 750. The FORM already fitted -- the submit button's bottom edge was at
 * 667 -- so what overflows is the page, and the gaps above the form are where the
 * space is.
 *
 * Two rules rather than one because the row and Bootstrap put the gap in two
 * places: .mt-5 on the form's own wrapper (the rule above, 16px) and .my-3 on the
 * div holding the operator's login_info copy (16px top AND bottom). The wrapper is
 * addressed as .mt-5.mb-5 so this cannot reach the logo block, which is .mt-5.mb-1
 * and keeps its own --gp-dimension-logo-gap-top.
 *
 * The 72px under the submit button is deliberately NOT touched: Corey asked for that
 * on the same review, and taking it back to buy 24px here would answer one note by
 * undoing another. */
#login .mt-5.mb-5 {
  margin-top: var(--gp-dimension-login-stack-gap) !important;
}

#login .my-3 {
  margin-top: var(--gp-dimension-login-stack-gap) !important;
  margin-bottom: var(--gp-dimension-login-stack-gap) !important;
}

/* The terms-of-service link. */
#login a {
  color: var(--gp-action-primary);
}

/* The only part of :725-731 that is not .gp-field__control. The weight, the colour,
 * the centring and the pill are all in the component; the fill is not, because it is
 * this page's alone -- the other three form pages sit on the page background and
 * ship Bootstrap's opaque white. Without this the fields turn solid at cutover and
 * the sky stops showing through them. */
#login .form-control {
  background-color: var(--gp-surface-glass-soft);
}

/* Copied character for character, ordering trap included -- `margin-bottom: 0
 * !important` followed by a `margin: auto` SHORTHAND that resets all four sides and
 * loses on the fourth, because importance beats source order. Identical to
 * #referrals-new .mb-5, and identically load-bearing: this is the 380px column the
 * form is centred in. */
#login .mb-5 {
  padding-right: 10px;
  padding-left: 10px;
  margin-bottom: 0 !important;
  width: 380px;
  margin: auto;
}

/* "Welcome! Please sign in", over the sky. */
#login h2 {
  margin-bottom: 2rem;
  color: var(--gp-text-on-image);
}

/* @login_help, rendered by ActionText. */
#login .trix-content {
  color: var(--gp-text-on-image);
}

/* font-size is DEAD -- `.mb-3 label` above is (1,1,1) against this rule's (1,1,0)
 * and bootstrap_form wraps every field in .mb-3, so 0.6rem has never painted. The
 * other two declarations are uncontested and do render, which is why the labels are
 * uppercase at 12px rather than at 9.6px. Same as #referrals-new .form-label; the
 * dead value is recorded on font/size-label in design/tokens.json rather than
 * re-typed here. */
#login .form-label {
  margin-bottom: 0rem !important;
  text-transform: uppercase;
}

#login .mb-3 {
  margin: 0.5rem !important;
}

/* baseline:770's 50px, rebound. The row writes it as `.mb-3:nth-child(4)`, and in
 * PRODUCTION -- where the form's first child is the CSRF hidden input -- child 4 was
 * the show-code group. Two things move that index and they move it in opposite
 * directions: the rewritten form inserts a .gp-field__msg after each field, and the
 * test environment turns forgery protection off so the fixture has no hidden input
 * at all. The index is therefore meaningless as a description of anything, and
 * porting it verbatim would paint a page nobody has seen.
 *
 * So the spacing is bound to the last element of the show-code group instead. Not to
 * the group itself: the message is a SIBLING after it now, and padding on the group
 * would push an error 50px away from the field it belongs to. */
/* margin-bottom, NOT padding-bottom, and the difference is the whole point of
 * .gp-field__msg. Bootstrap's reboot sets box-sizing: border-box, so 50px of
 * PADDING sits inside the box and is absorbed by the min-height: 1lh that
 * components.css:1353 reserves. Measured on the parity harness: this element came
 * back rect.h 50 while empty -- not 14.39 like its three siblings -- and grew to
 * 64.39 the moment an error string rendered into it. That is a 14.4px jump of
 * everything below, including the submit button, on the one field most likely to
 * be marked invalid, which is exactly the motion the reserved line exists to
 * prevent. Margin is outside the border box, so the reservation survives.
 *
 * It is NOT the same gap the row drew, and the difference is margin collapsing.
 * The row hung its 50px as PADDING on the .mb-3 wrapper, which cannot collapse, so
 * the wrapper's own `margin: 0.5rem !important` sat on top of it: 58px. Here the
 * 50px is margin on .gp-field__msg, it meets the terms .mb-3's 8px top margin, and
 * adjacent margins collapse to the larger of the two -- so what paints is 50px, not
 * 58px. What the checkbox loses there it more than gets back from the reserved line
 * itself: .gp-field__msg is min-height: 1lh, 14.39px of box that the row had no
 * element for at all. Measure the checkbox, not the gap, before calling this a
 * regression -- it sits LOWER than the row put it, by design, and that reserved
 * line is the whole point. */
#login #show_code_msg {
  margin-bottom: 50px;
}

/* The logged-out logo, which is the only thing left carrying either class -- the
 * submit button that used to wear .w-100 is a .gp-btn--block now. The width loses to
 * the max-width below, so the logo ships at 300px; both are carried because removing
 * either changes which value wins. */
#login .w-100 {
  width: 334px !important;
  font-size: 1rem !important;
}

#login .img-fluid {
  max-width: 300px;
}

/* Space above the Gross Prophets logo, which sat hard against the top of the
 * page (Corey, 2026-09-21).
 *
 * `.mt-5.mb-1` is the logged-out logo block in layouts/application and nothing
 * else: the other two elements `#login .mt-5` reaches -- the flash slot and the
 * form wrapper -- carry no .mb-1, which is the same discriminator the earlier
 * `.mt-5:not(.mb-1)` draft used, written the affirmative way round. (1,2,1)
 * against that rule's (1,1,0), and !important because the rule it has to beat
 * is itself !important.
 *
 * This is IN ADDITION to the safe-area inset: the layout's viewport-fit=cover
 * gives the body `padding-top: env(safe-area-inset-top)` (application.css), so
 * a notched iPhone gets its inset and then this on top. Judged after that inset
 * was in place, not before it. */
#login .mt-5.mb-1 {
  margin-top: var(--gp-dimension-logo-gap-top) !important;
}

/* ---------------------------------------------------------------------------
 * /shop -- baseline:836-1208 (981-1353 before the #login row cutover, PR #209)
 *
 * Moved verbatim. Five things in here are wrong and stay wrong, because a fix
 * would stop this being a verbatim move. Each is recorded in
 * docs/plans/shop-parity.md with the evidence:
 *
 *   - The background-image is an EXTERNAL squarespace CDN URL, not an app asset,
 *     so the shop's backdrop depends on a third party at showtime. The parity
 *     harness already blocks that host (script/parity_harness.rb BLOCKED_HOSTS).
 *     The real fix belongs with row-emptying, next to /login's digest path.
 *   - A stray `max` token sits between `-webkit-background-size` and
 *     `--background-size`, which takes both of those lines out as one invalid
 *     declaration.
 *   - `.card::before` and `.card::after` are written at column 0 but are still
 *     NESTED inside #shop -- CSS nesting ignores indentation. Do not "unindent
 *     fix" them out of the block.
 *   - `p.last-child` is a class selector, not `:last-child`, so its
 *     `background: red !important` is dead. That is why the shop is not red.
 *   - The `--background`, `--border`, `--box-shadow`, `--padding-top` and
 *     `--backdrop-filter` custom properties are read by nothing.
 * ------------------------------------------------------------------------ */
/* Shop Page */
#shop {
  
    background-image: url('https://images.squarespace-cdn.com/content/543df105e4b01ddd00dd714c/1740081796870-7CXTW4484HLW6OCBNOUT/image-asset.png?content-type=image%2Fpng'); 
  background-repeat: no-repeat; /* Prevent image tiling */
  background-attachment: fixed; /* Make the background image fixed relative to the viewport */
  background-position: center center; /* Center the image */
  background-size: cover; 
    -webkit-background-size: cover; /* For older WebKit versions */
max
  --background-size: contain, 100vh 100vw; 
  /*  background-size: contain, 100vh 100vw;

    background-repeat: no-repeat;
    background-position: center top;*/
  
  h1{
        margin-bottom: 2rem;
  color: white;}
  
  h1:first-child::after {
  content: 'Exchange your hard earned money for \A Chuds and Company™ Swag! \A \A  Order now and we\'ll deliver it to your seat!';
display: block;
   white-space: pre-wrap;
        font-size: .875rem;
        width: 275px;
        margin: auto;
        margin-top: 5px;
    font-style: italic;
        font-weight: 400;
        line-height: 1;  
    color: white;
  		margin-bottom: 5px;
}
  
  .fs-4.text-success p {
    color: var(--green);
  }
  
  [data-controller="product-options"] {
  padding:1rem;

  
  }
  [data-controller="product-options"] p {
   margin: 0;
  
  }
  

  .d-flex.justify-content-center.mt-5 {
    margin: 0 !important;
  }

  /* Quantity Label, Commission Label */
  label.me-2,
  label.form-label.required {
    font-size: 0.8rem;
    color: #3c3c3c;
    margin-bottom: 0;
  }

  /* Price */
  p.fs-4.text-success {
    margin-bottom: 0.5rem;
  }

  .quantity-selector {
    margin-bottom: 0.5rem !important;
  }

  .decreaseBtn {
    border-radius: 5rem;
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
    border:none;
  }

  .increaseBtn {
    border-radius: 5rem;
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    border:none;
  }

  input.btn.btn-lg {
    background-color: var(--green) !important;
    border-color: var(--green) !important;
    
    backdrop-filter: blur(2px) saturate(180%);
    --border: 1px solid rgba(255, 255, 255, 0.8);
    --box-shadow: 0 6px 16px rgba(31, 38, 135, 0.2),
      inset 0 4px 10px rgba(255, 255, 255, 0.3);
    border-radius: 20rem;
    backdrop-filter: blur(1px);
    font-size: 0.875rem;
 	color:white;
    height: 35px;

  }

  input.btn.btn-lg::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(255, 255, 255, 0.1);
    border-radius: 2rem;
    backdrop-filter: blur(1px);
    box-shadow: inset -10px -8px 0px -11px rgba(255, 255, 255, 1),
      inset 0px -9px 0px -8px rgba(255, 255, 255, 1);
    opacity: 0.6;
    z-index: -1;
    filter: blur(1px) drop-shadow(10px 4px 6px black) brightness(115%);
  }

  .form-control {
  background: transparent;
  
  }
  
  .trix-content {
    margin-top: 1rem;
    font-size: 14px;
    line-height: 1.3;
  }

  .form-select {
    border-radius: 5rem;
    height: 35px;
    font-size: 0.875rem;
    text-align:center;
  }

  .mb-3 {
    margin-bottom: 0.5rem !important;
  }
  
    .mb-5 {
    margin-bottom: 1rem !important;
  }
  
  
  .p-3 {
  padding: .5rem !important;
  }

  .input-group {
    border: 1px solid #ced4da;
    height: 35px;
    background: white;
    border-radius: 5em;
    backdrop-filter: blur(2px) saturate(180%);
    box-shadow:inset 0 4px 20px rgba(255, 255, 255, 0.3);
  }

    .input-group::after {
          content: "";
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: rgba(255, 255, 255, 0.1);
        border-radius: 2rem;
        --backdrop-filter: blur(1px);
        box-shadow: inset -10px -8px 0px -11px rgba(255, 255, 255, 1), inset 0px -9px 0px -8px rgba(255, 255, 255, 1);
        opacity: 0.6;
        z-index: -1;
        filter: blur(1px) drop-shadow(10px 3px 6px #888) brightness(122%);
    }
  
  .line_item_quantity {
  border:none;
  }

  .card .mt-3 {
    display: none;
}
  
  .card {
    border-radius: 16px;
    --padding-top: 0.4rem !important;
   
  }

  .img-fluid {
    max-width: 200px;
    width: auto;
  }

  h2 {
    margin-bottom: 0;
  }

  div[data-controller="product-options"] {
    display: flex;
    flex-direction: column;

    p.last-child {
    background: red!important;
    }
    
    
    h2 {
      order: -6;
    }
    p.fs-4.text-success {
      order: -5;
    }
    .quantity-selector.mb-3 {
      order: -4;
    }
    .mb-3 {
      order: -3;
    }
    input {
      order: -2;
    }
    .trix-content {
      order: -1;
font-size: 13px;
            color: #3c3c3c;
    }

    .input-group .decreaseBtn {
      order: -2;
    }

    .line_item_quantity {
      order: -1;
    }
    
    
    
    
  }

  .mt-3 {
    margin-bottom: 0;
    margin-top: 0;
    display:none;
  }

  /* Add to Cart Popup */

  .modal-content {
    background: white;
    backdrop-filter: blur(2px) saturate(180%);
    border: 1px solid rgba(255, 255, 255, 0.8);
    border-radius: 16px;
    box-shadow: 0 8px 16px rgba(31, 38, 135, 0.2),
      inset 0 4px 10px rgba(255, 255, 255, 0.3);
  }

  .modal-content::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(255, 255, 255, 0.1);
    border-radius: 16px;
    backdrop-filter: blur(1px);
    box-shadow: inset -10px -8px 0px -11px rgba(255, 255, 255, 1),
      inset 0px -9px 0px -8px rgba(255, 255, 255, 1);
    opacity: 0.6;
    z-index: -1;
    filter: blur(1px) drop-shadow(10px 4px 6px black) brightness(115%);
  }

  .modal-footer {
    border-bottom-right-radius: 16px;
    border-bottom-left-radius: 16px;
  }

  button.btn.btn-secondary,
  a.btn.btn-warning {
    height: 42px !important;

    position: relative;
    backdrop-filter: blur(2px) saturate(180%);
    border: 1px solid rgba(255, 255, 255, 0.8);
    border-radius: 2rem;
    box-shadow: 0 8px 16px rgba(31, 38, 135, 0.1),
      inset 0 4px 10px rgba(255, 255, 255, 0.2);
    border-radius: 50rem !important;
    display: flex;
    align-items: center;
  }

  button.btn.btn-secondary::after,
  a.btn.btn-warning::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(255, 255, 255, 0.1);
    border-radius: 2rem;
    backdrop-filter: blur(1px);
    box-shadow: inset -10px -8px 0px -11px rgba(255, 255, 255, 1),
      inset 0px -9px 0px -8px rgba(255, 255, 255, 1);
    opacity: 0.6;
    z-index: -1;
    filter: blur(1px) drop-shadow(10px 4px 6px black) brightness(115%);
  }

  button.btn.btn-secondary {
    background-color: var(--green);
  }

  a.btn.btn-warning {
    background-color: #ffffffb5;
  }

  .card {

 --background: rgba(255, 255, 255, 0.1) !important;
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-radius: 20px;
  border: 1px solid rgba(255, 255, 255, 0.3);
  box-shadow: 
    0 8px 32px rgba(0, 0, 0, 0.1),
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    inset 0 -1px 0 rgba(255, 255, 255, 0.1),
    inset 0 0 32px 16px rgba(255, 255, 255, 1.6);
  position: relative;
  overflow: hidden;
}

.card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(255, 255, 255, 0.8),
    transparent
  );
}

.card::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 100%;
  background: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.8),
    transparent,
    rgba(255, 255, 255, 0.3)
  );
}

  .card.bg-light {
    --background: #f9fafb00;
      background: rgba(255, 255, 255, .8) !important;


  }
}
