/**
 * /cat/assets/css/entry.css
 *
 * The public entry page.
 *
 * ── THE IDEA ────────────────────────────────────────────────────────────────
 * The parishes are named for saints and represented by ICONS — Byzantine and
 * Maronite, gold leaf, halo, flat planes. The first draft put those in small
 * grey circles like avatars on a settings screen, which threw away the one
 * distinctive material this portal has. So the page is built as an icon panel:
 * a deep field, a gilded ring, generous margin around the image, and everything
 * else kept quiet so the crest carries the page.
 *
 * The second organising fact is that this system orbits an academic YEAR that
 * opens and closes. It is not a subtitle; it is the thing the whole portal is
 * about. So it sits above the parish name as a letterspaced eyebrow, which is
 * where the eye lands first.
 *
 * Palette and the .adm-* components come from admin-theme.css, per install via
 * data-theme. This file adds only what the entry page needs.
 *
 * @version 3.9.0
 *
 * Changelog
 *   3.9.0 — .ent-rtl-name — Cairo and right alignment for an input holding an
 *           Arabic name. The dir attribute alone fixes the caret and the reading
 *           order but leaves the text in the body's Latin face, where an Arabic
 *           run falls back to whatever the system has. The same fault 3.1.0
 *           fixed for the page at large, reappearing one input at a time.
 *   3.8.0 — .ent-hint--rule. The birth-year sentence on the parents mini-form
 *           decides whether a family can register at all, and it was set in the
 *           same quiet grey as a placeholder. Now it reads as a rule.
 *   3.7.0 — .ent-dupname, for a masked parent name inside the duplicate notice.
 *
 *           On Saint Mary those names are ARABIC and the sentence around them is
 *           English, so the name is an RTL island in LTR prose. Without
 *           unicode-bidi: isolate the name's direction leaks into the sentence
 *           and the punctuation reorders around it.
 *
 *           Cairo explicitly, because the notice inherits the body font and an
 *           Arabic run in a Latin face falls back to whatever the system has —
 *           the same fault 3.1.0 fixed for the page at large.
 *   3.6.0 — .ent-dupwarn, the duplicate-child notice on the parents mini-form.
 *
 *           When check_child finds a child of this name and birth date already
 *           registered to a parent of this name, the form says so and names the
 *           family with both parents' names masked. It is ADVISORY: there is no
 *           dismiss button and Send code is never disabled. Only the parent can
 *           say whether the record we found is theirs, so the system tells them
 *           and gets out of the way.
 *
 *           Amber rather than red, and THEMED rather than hardcoded — the same
 *           correction 3.4.0 made to .ent-notice. A literal #fdf7ea would be
 *           parchment on both installs instead of parchment on rosary and sand
 *           on marine.
 *   3.5.0 — Two classes the parents mini-form referenced and this file never
 *           defined: .ent-minihead and .ent-radioset--inline. Both were
 *           invented in the markup, so they carried no styles at all —
 *           .ent-minihead's two spans rendered inline against each other
 *           ("Your childالولد"), and the role pills stretched full-width and
 *           read as panels rather than as a choice.
 *           .ent-label--ask is new alongside them, for a label that asks a
 *           question rather than naming a field.
 *   3.4.0 — .ent-notice (the maintenance/test banner) now aligns with the form
 *           shell instead of protruding past it, and takes its colours from the
 *           theme.
 *
 *           WHAT WAS WRONG: the notice is a sibling BETWEEN .ent-panel and
 *           .ent-shell, but only the shell carried the lift into the panel
 *           (margin-top:-3.25rem) and the inset (margin-inline:1.25rem). So the
 *           shell rode up OVER the notice and the notice, being full-width,
 *           showed only as two tabs sticking out either side. Visible on
 *           echristianae because staff_test_mode is on there and off on Qatar —
 *           which is why it looked like a per-install layout bug and was not.
 *
 *           The notice now takes the lift and the inset, and the shell that
 *           FOLLOWS it drops its own lift (.ent-notice + .ent-shell), so the two
 *           stack cleanly inside the panel's lower edge. With no notice present,
 *           nothing changes.
 *
 *           Colours were hardcoded amber — one of the last literals left after the
 *           v3.0.0 merge. Now --adm-well / --adm-line / --adm-accent, so the
 *           banner is parchment-and-gold on rosary and sand-and-amber on marine
 *           rather than the same yellow on both.
 *   3.3.0 — Both entry pages move onto MDB's .container width curve. The landing
 *           page sat at a custom 900px and the form column at 640px, set
 *           independently, so the form read as cowering under a masthead half
 *           again its width. The curve is reproduced HERE rather than by adding
 *           .container to the markup, so parents_entry.php inherits it without
 *           anyone remembering to add a class — markup is what drifts between
 *           installs. .ent-col no longer sets a width at all: it shares an
 *           element with .ent-wrap (staff_entry.php's <main>) and was only ever
 *           overriding it by coming later in the file.
 *   3.2.1 — .ent-orsplit now overrides Bootstrap's .row/.col box model — those
 *           classes had to stay in the markup for FormValidation's sake, and .row
 *           brings negative margins and gutter padding that fought the flex row.
 *   3.2.0 — The footer is NEUTRAL dark (#23272b), not the theme primary: on the
 *           rosary theme a burgundy band sat directly under a burgundy panel and
 *           the two read as competing slabs. Full width too — boxed inside the
 *           640px form column it looked gripped to the form rather than closing
 *           the page.
 *   3.1.0 — (a) The form shell now LIFTS into the panel, the same overlap the
 *           landing cards use — the gate read as two stacked blocks.
 *           (b) Cairo is bound to [lang="ar"], [dir="rtl"] and .ar as well as
 *           .ent-body, so an Arabic run gets it even on a page that forgot the
 *           body class. That is precisely how the staff gate lost it.
 *           (c) The footer is DARK and anchors the page; white on sand read as
 *           unfinished space. Sticky, not fixed — fixed would eat room on a phone
 *           where the tall steps need it.
 *   3.0.0 — MERGED: staff_entry.css folded in, so index.php, staff_entry.php and
 *           (next) parents_entry.php share one stylesheet and one look. The staff
 *           gate had its OWN hardcoded burgundy palette and so ignored ui_theme
 *           entirely — it rendered in Qatar's colours on echristianae. Four class
 *           names collided and were renamed on the FORM side, the landing page
 *           being the reference; staff_entry.js touches none of them.
 *           Also: the panel gained bottom room so its Arabic subtitle clears the
 *           card that overlaps it, and the mobile-or-email choice gained a disc
 *           between the fields (.ent-orsplit / .ent-ordisc).
 *   2.3.4 — The footer wrapper is a centred ROW, not a column. As a column it
 *           stacked each child's icon above its own text, so the state box ran to
 *           three lines and the button to two — unequal again, for a new reason.
 *   2.3.3 — The "closes on" line is gone: it told someone about to press Enter a
 *           date eight months off, and it was the only thing making the open card
 *           taller than the closed one. The footer minimum moved onto a wrapper
 *           that centres its contents rather than stretching the button itself.
 *   2.3.2 — Year band larger, bolder, in the theme primary. The heading row has
 *           a two-line minimum height so the gold rule lands at the same place on
 *           both cards — "Parents" wraps to one line and "Catechists &
 *           volunteers" to two, which had everything below them out of step.
 *   2.3.1 — The year is a BAND across the head of the card (.ent-year-band), not
 *           a stray line above the icon. And the heading rule moved onto the ROW:
 *           it had stayed on each name, giving two stubby underlines that read as
 *           two headings rather than one in two scripts.
 *   2.3.0 — Route heading is one line in two scripts (.ent-name-row), with the
 *           rule under both — stacked, the Arabic read as a subtitle rather than
 *           the same heading. The year moved to the top of the card.
 *   2.2.3 — .ent-name-ar for the Arabic route headings.
 *   2.2.2 — The card row is inset from the panel's edges. Flush, the two were
 *           the same width by coincidence; inset, the panel reads as the thing
 *           the cards sit in.
 *   2.2.1 — The overlap is back, done properly: the cards lift into the panel
 *           and the panel carries enough bottom padding for them to land in.
 *           v2.0 had the lift without the room, so it read as a collision; v2.2
 *           removed the lift, which lost the layering that ties the two halves
 *           together.
 *   2.2.0 — Per-parish colour via a --tint custom property, set
 *           inline from fixed_parameters.parish_tint and falling back to the
 *           theme primary, so two parishes are distinguishable at a glance
 *           without a second theme.
 *   2.1.0 — Cairo actually APPLIED (declared but never used, so everything fell
 *           back to the system sans). Change-parish moved into the panel corner
 *           — centred, it read as the panel's main action. Card footers share a
 *           minimum height so the pair sits level whatever each state says.
 *   2.0.0 — Reworked. v1 was three flat boxes on an empty page, with the state
 *           pill and the disabled button repeating the same words directly above
 *           one another. Now: gilded icon panel, the year as an eyebrow, route
 *           cards distinguished by colour and rule, and a CLOSED route shows no
 *           button at all — the state line IS the message, so nothing is said
 *           twice.
 *   1.0.0 — Initial.
 */

/* ── Page ─────────────────────────────────────────────────────────────────── */
/* Cairo, applied. cairo.css only DECLARES the face — loading it and never using
   it left the page in the browser's default sans, with the Arabic falling back to
   whatever the system happened to have.
   Also bound to [lang="ar"], [dir="rtl"] and .ar so an Arabic run is Cairo even on
   a page that forgot the body class — which is exactly how the staff gate lost it. */
.ent-body,
.ent-body input,
.ent-body button,
[lang="ar"],
[dir="rtl"],
.ar {
    font-family: "Cairo", system-ui, -apple-system, "Segoe UI", sans-serif;
}

.ent-body {
    background:
        radial-gradient(1200px 420px at 50% -180px, var(--adm-primary-050), transparent 70%),
        var(--adm-well);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

/* The container curve, matching MDB/Bootstrap's .container so the entry pages
   line up with everything else in the product. Reproduced HERE rather than by
   putting .container in the markup: this file already serves all three entry
   pages, so the width lives in one place and parents_entry.php inherits it
   without anyone remembering to add a class. Markup is what drifts between
   installs.
   staff_entry.php's <main> carries BOTH .ent-wrap and .ent-col on the same
   element, so this is the width for both pages. */
.ent-wrap {
    flex: 1 0 auto;
    width: 100%;
    margin: 0 auto;
    padding: 3.5rem 1.15rem 4rem;
}

@media (min-width: 576px) {
    .ent-wrap {
        max-width: 540px;
    }
}

@media (min-width: 768px) {
    .ent-wrap {
        max-width: 720px;
    }
}

@media (min-width: 992px) {
    .ent-wrap {
        max-width: 960px;
    }
}

@media (min-width: 1200px) {
    .ent-wrap {
        max-width: 1140px;
    }
}

@media (min-width: 1400px) {
    .ent-wrap {
        max-width: 1320px;
    }
}

/* ── The panel ────────────────────────────────────────────────────────────── */
/* A single deep field carrying the crest, the year and the parish. The gold
   hairline is the frame of an icon, not a decorative border — it is the one
   flourish, and everything else stays quiet so it reads. */
.ent-panel {
    position: relative;
    background:
        radial-gradient(680px 300px at 50% -60px, rgba(255, 255, 255, .10), transparent 70%),
        linear-gradient(160deg, var(--adm-primary-700), var(--adm-primary));
    border: 1px solid var(--adm-accent-bright);
    border-radius: 1rem;
    padding: 2.75rem 1.5rem 5.25rem;
    text-align: center;
    color: #fff;
    box-shadow: var(--adm-shadow-lg);
    overflow: hidden;
}

/* Inner hairline: the double frame an icon panel actually has. */
.ent-panel::after {
    content: "";
    position: absolute;
    inset: .4rem;
    border: 1px solid rgba(255, 255, 255, .16);
    border-radius: .75rem;
    pointer-events: none;
}

.ent-crest {
    width: 8.5rem;
    height: 8.5rem;
    border-radius: 50%;
    object-fit: cover;
    display: block;
    margin: 0 auto 1.4rem;
    border: 3px solid var(--tint-ring, var(--adm-accent-bright));
    box-shadow: 0 0 0 .55rem rgba(0, 0, 0, .14), 0 .5rem 1.5rem rgba(0, 0, 0, .3);
    background: var(--adm-well);
}

/* The year, not the parish, is what the portal orbits — so it leads. */
.ent-eyebrow {
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .22em;
    text-transform: uppercase;
    color: var(--adm-accent-soft);
    margin: 0 0 .5rem;
}

.ent-title {
    font-size: 1.75rem;
    font-weight: 700;
    line-height: 1.25;
    margin: 0;
    color: #fff;
}

.ent-lede-ar {
    font-size: 1.05rem;
    margin: .35rem 0 0;
    color: rgba(255, 255, 255, .82);
}

.ent-title-ar {
    font-size: 1.15rem;
    font-weight: 400;
    margin: .3rem 0 0;
    color: rgba(255, 255, 255, .82);
}

.ent-lede {
    font-size: .95rem;
    margin: .85rem auto 0;
    max-width: 30rem;
    color: rgba(255, 255, 255, .8);
}

.ent-change {
    /* In the panel's corner rather than centred beneath the name: as a centred
       pill it read as the panel's main action, which it is not — it is an escape
       hatch for the few who chose wrongly. */
    position: absolute;
    top: 1rem;
    right: 1rem;
    z-index: 3;
    font-size: .78rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--adm-accent-soft);
    border: 1px solid rgba(255, 255, 255, .32);
    border-radius: 999px;
    padding: .32rem 1rem;
    text-decoration: none;
    transition: background .15s ease;
}

.ent-change:hover,
.ent-change:focus-visible {
    background: rgba(255, 255, 255, .14);
    color: #fff;
}

/* ── Cards ────────────────────────────────────────────────────────────────── */
.ent-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
    gap: 1.25rem;
    /* The cards sit INTO the panel's lower edge — that overlap is what ties the
       two halves together. v2 had the same lift but the panel was too shallow
       beneath the text, so the crest and the card corners fought for the same
       pixels and it read as a collision rather than a deliberate layer. The
       panel now carries enough bottom padding for the cards to land in. */
    margin-top: -2.75rem;
    /* Narrower than the panel, so the panel reads as the container and the cards
       as sitting IN it. Flush edges made the two the same width by coincidence
       rather than by relationship, and the layering lost its point. */
    margin-inline: 1.75rem;
    position: relative;
    z-index: 2;
}

.ent-card {
    background: var(--adm-surface);
    border: 1px solid var(--adm-line);
    border-radius: .85rem;
    box-shadow: var(--adm-shadow);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    transition: transform .15s ease, box-shadow .15s ease;
}

/* Parish cards are the whole target — a small link inside a large card is a
   smaller hit area than the card the eye is already on. */
a.ent-card {
    text-decoration: none;
    color: inherit;
}

a.ent-card:hover,
a.ent-card:focus-visible {
    transform: translateY(-2px);
    box-shadow: var(--adm-shadow-lg);
}

/* Each parish carries its own colour, set inline from fixed_parameters.
   parish_tint. It falls back to the theme primary, so an install that has not
   set one looks exactly as before. */
.ent-card {
    --tint: var(--adm-primary);
}

.ent-card__top {
    height: 4px;
    background: var(--tint);
}

.ent-card--accent .ent-card__top {
    background: var(--adm-accent);
}

.ent-card__body {
    padding: 1.35rem 1.35rem 1.15rem;
    flex: 1 1 auto;
}

.ent-route-icon {
    font-size: 1.6rem;
    color: var(--tint);
    margin-bottom: .75rem;
    display: block;
}

.ent-card--accent .ent-route-icon {
    color: var(--adm-accent);
}

/* One heading, two scripts, one line — English hard left, Arabic hard right, and
   ONE rule under the pair. Previously the rule sat on each name, which produced
   two stubby underlines and made them read as two separate headings. */
.ent-name-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .75rem;
    margin: 0 0 .85rem;
    padding-bottom: .5rem;
    border-bottom: 2px solid var(--adm-accent-bright);
    /* Two lines' worth, so the rule sits at the SAME height on every card.
       "Parents" is one line and "Catechists & volunteers" is two, and without
       this the two rules — and everything below them — sat at different
       heights, which reads as misalignment rather than as different content. */
    min-height: 3.6rem;
    align-items: flex-end;
}

.ent-name-row .ent-name {
    flex: 0 1 auto;
    border-bottom: 0;
    /* the ROW carries the rule, never the name */
    padding-bottom: 0;
    margin: 0;
}

.ent-name-row .ent-name:last-child {
    text-align: right;
}

.ent-name {
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--adm-ink);
    margin: 0;
    line-height: 1.35;
}

/* Parish cards use .ent-name alone, centred, with its own rule. */
a.ent-card .ent-name {
    display: inline-block;
    padding-bottom: .55rem;
    border-bottom: 2px solid var(--adm-accent-bright);
    margin-bottom: .55rem;
}

/* Narrow cards: stack rather than squeeze, each name on its own side. */
@media (max-width: 400px) {
    .ent-name-row {
        display: block;
        min-height: 0;
    }

    .ent-card__foot>* {
        min-height: 0;
    }

    .ent-name-row .ent-name:last-child {
        display: block;
        margin-top: .25rem;
    }
}

.ent-blurb {
    font-size: .9rem;
    line-height: 1.65;
    color: var(--adm-body);
    margin: 0;
}

.ent-card__foot {
    padding: 1rem 1.35rem 1.35rem;
}

/* ── State ────────────────────────────────────────────────────────────────── */
/* v1 showed a pill AND a disabled button carrying the same words, one directly
   under the other. A closed route now shows the state line ONLY: it is the whole
   message, and it carries the date or the address that makes it useful. */
/* Both cards' footers land at the same depth whatever their state.
   The minimum is on a WRAPPER that CENTRES its contents, not on the child: put on
   the child it stretched the BUTTON to fill it — a 4.6rem slab where a button
   wants about 2.6rem — while the state box, carrying its own padding, still ended
   somewhere else.

   And the direction must be a ROW. As a column it stacked each element's own
   children: the clock above its words, the door icon above "Enter" — so the box
   grew to three lines and the button to two, and they were unequal again for a
   new reason. align-items on a row centres the block vertically while leaving the
   icon beside its text, which is where it belongs. */
.ent-card__foot>* {
    min-height: 4.2rem;
    display: flex;
    align-items: center;
    /* NOT column — see below */
}

.ent-state {
    display: flex;
    align-items: center;
    gap: .65rem;
    font-size: .88rem;
    line-height: 1.5;
    padding: .7rem .85rem;
    border-radius: .5rem;
    border: 1px solid transparent;
}

.ent-state i {
    margin-top: .15rem;
    flex: 0 0 auto;
}

.ent-state--soon {
    background: #FAEEDA;
    border-color: #ecd9b4;
    color: #6f420a;
}

.ent-state--closed {
    background: #f4f1ec;
    border-color: var(--adm-line);
    color: #5a5348;
}

.ent-state--paused {
    background: #eef2f5;
    border-color: #dbe3ea;
    color: #384a57;
}

.ent-state strong {
    font-weight: 700;
}

.ent-state a {
    color: inherit;
    font-weight: 700;
    text-decoration: underline;
}

.ent-enter {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    text-align: center;
    padding: .7rem 1rem;
    border-radius: .5rem;
    background: var(--tint);
    color: #fff;
    font-weight: 600;
    text-decoration: none;
    border: 1px solid var(--tint);
    transition: filter .15s ease;
}

.ent-card--accent .ent-enter {
    background: var(--adm-accent);
    border-color: var(--adm-accent);
}

.ent-enter:hover,
.ent-enter:focus-visible {
    filter: brightness(.92);
    color: #fff;
}

/* Which year this card means — a BAND across the head of the card, not a stray
   line above the icon. Parents and catechists can sit on DIFFERENT years during a
   rollover, so each card states its own before anything else. */
.ent-year-band {
    background: var(--adm-well);
    border-bottom: 1px solid var(--adm-line);
    padding: .6rem .75rem;
    text-align: center;
    font-size: .95rem;
    font-weight: 700;
    letter-spacing: .1em;
    color: var(--adm-primary);
}

/* ── Contact + footer ─────────────────────────────────────────────────────── */
.ent-contact {
    text-align: center;
    font-size: .9rem;
    color: var(--adm-body);
    margin: 2rem 0 0;
}

.ent-contact a {
    color: var(--adm-primary);
    font-weight: 600;
}

/* Full-width, and NEUTRAL dark rather than the theme's primary.
   Primary was tried and is wrong: on the rosary theme a burgundy band sits
   directly under a burgundy panel, and the two read as competing slabs with the
   page's content marooned between them. A neutral dark sits under either palette
   without arguing with it, and the gold rule keeps it in the family.

   It must be a sibling of <main>, NOT inside the form column — boxed at 640px it
   looked gripped to the form instead of closing the page. */
.ent-foot {
    flex-shrink: 0;
    width: 100%;
    text-align: center;
    padding: 1.5rem 1rem;
    font-size: .8rem;
    color: rgba(255, 255, 255, .68);
    background: #23272b;
    border-top: 2px solid var(--adm-accent-bright);
}

.ent-foot a {
    color: var(--adm-accent-soft);
}

.ent-foot div+div {
    margin-top: .2rem;
}

/* ── Small screens ────────────────────────────────────────────────────────── */
@media (max-width: 575.98px) {
    .ent-wrap {
        padding: 2rem .9rem 2.5rem;
    }

    .ent-panel {
        padding: 2rem 1.1rem 4.25rem;
    }

    .ent-crest {
        width: 6.75rem;
        height: 6.75rem;
    }

    .ent-title {
        font-size: 1.4rem;
    }

    .ent-grid {
        margin-top: -2rem;
        margin-inline: .5rem;
    }
}

@media (prefers-reduced-motion: reduce) {

    a.ent-card,
    .ent-enter,
    .ent-change {
        transition: none;
    }

    a.ent-card:hover {
        transform: none;
    }
}

/* =============================================================================
 * ENTRY FLOW — the staff and parents registration gates
 *
 * Folded in from cat/staff/assets/css/staff_entry.css v0.4.0, which had its OWN
 * :root palette — burgundy, gold, parchment, hardcoded — so on echristianae the
 * staff gate rendered in Qatar's colours whatever ui_theme said. Everything below
 * now reads the themed variables above, and the two pages finally look like one
 * product.
 *
 * Four class names collided with the landing page's and were renamed HERE, not
 * there, since the landing page is the reference:
 *     .ent-card  → .ent-shell        (the white form shell)
 *     .ent-panel → .ent-step-panel   (one step of the stepper)
 *     .ent-h2    → .ent-form-h2      (a step's heading)
 *     .ent-wrap  → .ent-col          (the form column)
 * staff_entry.js references none of the four, so no JS change was needed. Every
 * class the JS DOES read — .ent-affix, .ent-pill, .ent-otp-box, .ent-step — keeps
 * its name exactly.
 * ========================================================================== */

/* .ent-col shares its element with .ent-wrap — staff_entry.php's <main> carries
   both — so the width comes from there and the two pages are the same width by
   construction rather than by coincidence. It stays as a hook for form-side rules
   and for parents_entry.php. */
.ent-col {
    width: 100%;
    margin: 0 auto;
}

/* The shell lifts INTO the panel above it, the same overlap the landing page's
   cards use — otherwise the gate reads as two stacked blocks where the landing
   page reads as one composition. Inset, so the panel is visibly the container. */
.ent-shell {
    margin-top: -3.25rem;
    margin-inline: 1.25rem;
    position: relative;
    z-index: 2;
}

@media (max-width: 575.98px) {
    .ent-shell {
        margin-top: -2.25rem;
        margin-inline: .35rem;
    }
}

/* The purpose of the page, banded across the head of the form shell. The parish
   belongs in the panel above — it is stable, and it is where you ARE; the errand
   changes per page and belongs with the thing that performs it. */
.ent-purpose {
    background: var(--adm-well);
    border-bottom: 1px solid var(--adm-line);
    padding: .85rem 1.15rem;
    text-align: center;
}

.ent-purpose__en {
    margin: 0;
    font-size: 1rem;
    font-weight: 700;
    color: var(--adm-primary);
    line-height: 1.3;
}

.ent-purpose__ar {
    margin: .15rem 0 0;
    font-size: .9rem;
    color: var(--adm-accent);
}

/* ── The OR between mobile and email ──────────────────────────────────────── */
/* A trailing "enter one of the two" line was too quiet — two boxes side by side
   read as two things to fill. The disc sits BETWEEN them, so the choice is part
   of the layout rather than a note about it. */
/* The .row/.col grid classes stay on this element for FormValidation's benefit —
   its Bootstrap5 plugin walks up looking for a row container and throws on null
   if there isn't one. So these rules have to beat Bootstrap's own .row, which is
   flex with negative margins and per-child padding gutters. */
.ent-orsplit {
    display: flex;
    align-items: flex-end;
    gap: .85rem;
    margin: 0;
    /* .row's negative gutter margins */
    --bs-gutter-x: 0;
    --bs-gutter-y: 0;
}

.ent-orsplit>.ent-orside {
    flex: 1 1 0;
    min-width: 0;
    width: auto;
    /* .col-md-6 sets 50% */
    max-width: none;
    padding: 0;
    /* .col's gutter padding */
    margin: 0;
}

.ent-ordisc {
    flex: 0 0 auto;
    width: 2.6rem;
    height: 2.6rem;
    margin-bottom: 1.35rem;
    /* sits level with the fields, not their labels */
    border-radius: 50%;
    background: var(--adm-primary);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: .82rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    box-shadow: 0 .15rem .5rem rgba(var(--adm-shadow-rgb), .25);
}

/* Narrow: the fields stack, and the disc becomes a rule with the word in it —
   a floating circle between stacked boxes reads as an ornament, not a choice. */
@media (max-width: 575.98px) {
    .ent-orsplit {
        display: block;
    }

    .ent-orsplit>.ent-orside {
        width: 100%;
    }

    .ent-ordisc {
        width: auto;
        height: auto;
        margin: .25rem 0 1rem;
        border-radius: 999px;
        padding: .3rem 0;
        background: transparent;
        color: var(--adm-accent);
        box-shadow: none;
        position: relative;
    }

    .ent-ordisc::before,
    .ent-ordisc::after {
        content: "";
        flex: 1;
        height: 1px;
        background: var(--adm-line);
        margin: 0 .75rem;
    }
}

/* The sentence that prevents a duplicate record. It was trailing the end of a
   paragraph, where it read as an aside; it is the single most consequential line
   on the step. */
.ent-samechannel {
    display: block;
    margin-top: .35rem;
    font-weight: 700;
    color: var(--adm-accent);
}

/* ── Maintenance notice ─────────────────────────────────────────────────── */
/* The notice sits BETWEEN the panel and the shell, so it — not the shell — is
   what lifts into the panel's lower edge when present. It therefore carries the
   same lift and inset the shell normally has, and the shell that follows drops
   its own (see below). Without this the shell rode up over the notice and only
   its protruding edges showed. */
.ent-notice {
    display: flex;
    align-items: center;
    gap: 10px;
    background: var(--adm-well);
    border: 1px solid var(--adm-line);
    color: var(--adm-accent);
    border-radius: 10px;
    padding: 10px 14px;
    font-size: 13px;
    margin-top: -3.25rem;
    margin-inline: 1.25rem;
    margin-bottom: 18px;
    position: relative;
    z-index: 2;
}

/* When a notice precedes the shell it has already done the lifting. */
.ent-notice+.ent-shell {
    margin-top: 0;
}

@media (max-width: 575.98px) {
    .ent-notice {
        margin-top: -2.25rem;
        margin-inline: .35rem;
    }
}

/* ── Card ───────────────────────────────────────────────────────────────── */
.ent-shell {
    background: #fff;
    border: 1px solid var(--adm-line);
    border-radius: 16px;
    box-shadow: 0 10px 30px rgba(var(--adm-shadow-rgb), .10);
    padding: 0;
    overflow: hidden
}

/* ── Step rail ──────────────────────────────────────────────────────────── */
.ent-steps {
    display: flex;
    gap: 0;
    margin: 0;
    padding: 0;
    list-style: none;
    background: var(--adm-well);
    border-bottom: 1px solid var(--adm-line)
}

.ent-step {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    font-size: 13px;
    font-weight: 600;
    color: var(--adm-muted);
    padding: 12px 6px;
    position: relative
}

.ent-step .n {
    width: 22px;
    height: 22px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: #fff;
    border: 1.5px solid var(--adm-line);
    font-size: 12px;
    font-weight: 700;
    color: var(--adm-muted)
}

.ent-step.is-current {
    color: var(--adm-primary)
}

.ent-step.is-current .n {
    background: var(--adm-primary);
    border-color: var(--adm-primary);
    color: #fff
}

.ent-step.is-done .n {
    background: var(--adm-accent-bright);
    border-color: var(--adm-accent-bright);
    color: #fff
}

.ent-step.is-done {
    color: var(--adm-accent)
}

/* ── Panels ─────────────────────────────────────────────────────────────── */
.ent-step-panel {
    padding: 26px 24px 28px;
    animation: entFade .25s ease both
}

.ent-step-panel[hidden] {
    display: none
}

@keyframes entFade {
    from {
        opacity: 0;
        transform: translateY(6px)
    }

    to {
        opacity: 1;
        transform: none
    }
}

@media (prefers-reduced-motion: reduce) {
    .ent-step-panel {
        animation: none
    }
}

.ent-form-h2 {
    font-size: 19px;
    font-weight: 800;
    color: var(--adm-primary);
    margin: 0 0 6px
}

.ent-lead {
    font-size: 14px;
    color: #4a463f;
    margin: 0 0 4px;
    line-height: 1.5
}

.ent-lead-ar {
    font-family: "Cairo", sans-serif;
    font-size: 13.5px;
    color: var(--adm-muted);
    margin: 4px 0 14px
}

.ent-or {
    font-size: 12.5px;
    color: var(--adm-muted);
    margin: 10px 0 0
}

/* ── Labels ─────────────────────────────────────────────────────────────── */
.ent-label {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    font-size: 13px;
    font-weight: 700;
    color: var(--adm-primary);
    margin: 0 0 6px
}

.ent-label .ar {
    font-weight: 700;
    color: var(--adm-accent);
    font-size: 12.5px
}

/* ── Affix (matches the registration form's single-box affix) ───────────── */
.ent-affix {
    display: flex;
    align-items: stretch;
    height: 44px;
    border: 1px solid var(--adm-line);
    border-radius: 8px;
    overflow: hidden;
    background: #fff
}

.ent-affix .affix {
    display: flex;
    align-items: center;
    padding: 0 12px;
    background: var(--adm-well);
    color: var(--adm-accent);
    font-weight: 700;
    font-size: 13.5px;
    border-inline-end: 1px solid var(--adm-line);
    border-radius: 7px 0 0 7px;
    white-space: nowrap
}

.ent-affix .form-control {
    border: none;
    box-shadow: none;
    height: 100%;
    background: transparent;
    font-size: 14px;
    padding: 0 12px
}

.ent-affix .form-control:focus {
    box-shadow: none
}

.ent-affix:focus-within {
    border-color: var(--adm-accent-bright);
    box-shadow: 0 0 0 3px rgba(var(--adm-accent-rgb), .18)
}

/* FormValidation.io (Bootstrap5 plugin) integration — mirrors registration.php's
   single-box affix model. The plugin wraps the input in .fv-plugins-icon-container
   and toggles is-invalid / is-valid on the input; we lift the red/green ring onto
   the WHOLE .ent-affix box and keep the inner input borderless. */
.ent-affix .fv-plugins-icon-container {
    flex: 1 1 auto;
    min-width: 0;
    display: flex
}

.ent-affix .fv-plugins-icon-container>.form-control {
    flex: 1 1 auto;
    min-width: 0;
    width: 100%;
    height: 100%;
    border: none !important;
    background: transparent !important;
    box-shadow: none !important;
    border-radius: 0 !important;
    padding: 0 12px
}

.ent-affix .fv-plugins-icon {
    display: none !important
}

/* neutralise the input's own is-invalid/is-valid border (ring goes on the box) */
.ent-affix .form-control.is-invalid,
.ent-affix .form-control.is-valid {
    border: none !important;
    box-shadow: none !important;
    background-image: none !important
}

/* red box when invalid, green when valid */
.ent-affix:has(.is-invalid) {
    border-color: var(--adm-danger) !important;
    box-shadow: 0 0 0 3px rgba(198, 40, 40, .14)
}

.ent-affix:has(.is-invalid) .affix {
    border-inline-end-color: var(--adm-danger)
}

.ent-affix:has(.is-valid) {
    border-color: var(--adm-success) !important;
    box-shadow: 0 0 0 3px rgba(31, 122, 61, .12)
}

.ent-affix:has(.is-valid) .affix {
    border-inline-end-color: var(--adm-success)
}

/* FV message under the affix box */
.ent-affix>.fv-plugins-message-container,
.ent-affix .fv-plugins-icon-container+.fv-plugins-message-container {
    position: absolute;
    top: 100%;
    left: 0;
    width: 100%;
    margin-top: 3px
}

/* the affix needs a positioning context + room for the message below it */
.ent-affix {
    position: relative;
    margin-bottom: 20px
}

/* row-level FV classes can draw their own border — neutralise (no doubled ring) */
.fv-plugins-bootstrap5-row-invalid,
.fv-plugins-bootstrap5-row-valid {
    border: none !important;
    background: none !important;
    box-shadow: none !important
}

/* ── Buttons ────────────────────────────────────────────────────────────── */
.ent-actions {
    margin-top: 18px;
    display: flex;
    gap: 10px;
    flex-wrap: wrap
}

.ent-btn-primary {
    background: var(--adm-primary);
    color: #fff;
    border: none;
    border-radius: 9px;
    padding: 11px 22px;
    font-weight: 700;
    font-size: 14px;
    cursor: pointer;
    transition: background .15s ease, transform .05s ease
}

.ent-btn-primary:hover {
    background: var(--adm-primary-700)
}

.ent-btn-primary:active {
    transform: translateY(1px)
}

.ent-btn-primary:disabled {
    opacity: .55;
    cursor: not-allowed
}

.ent-btn-primary .ar {
    font-weight: 700;
    opacity: .85
}

.ent-btn-ghost {
    background: #fff;
    color: var(--adm-primary);
    border: 1.5px solid var(--adm-line);
    border-radius: 9px;
    padding: 11px 20px;
    font-weight: 700;
    font-size: 14px;
    cursor: pointer;
    transition: border-color .15s, background .15s
}

.ent-btn-ghost:hover {
    border-color: var(--adm-primary);
    background: var(--adm-primary-050)
}

.ent-btn-ghost .ar {
    font-weight: 700;
    opacity: .8
}

/* disabled (mutually-exclusive) affix field */
.ent-affix.is-disabled {
    background: var(--adm-inert-bg);
    opacity: .6
}

.ent-affix.is-disabled .affix {
    background: var(--adm-inert-line)
}

.ent-affix.is-disabled .form-control {
    cursor: not-allowed
}

.ent-back,
.ent-link {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--adm-accent);
    font-size: 13px;
    font-weight: 600;
    padding: 0;
    text-decoration: underline;
    text-underline-offset: 2px
}

.ent-back {
    margin-bottom: 14px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    text-decoration: none
}

.ent-back:hover {
    color: var(--adm-primary)
}

.ent-link:disabled {
    color: var(--adm-muted);
    cursor: default;
    text-decoration: none
}

/* ── Channel pills ──────────────────────────────────────────────────────── */
.ent-radioset {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 6px
}

.ent-pill {
    position: relative;
    cursor: pointer;
    flex: 1;
    min-width: 180px
}

.ent-pill input {
    position: absolute;
    opacity: 0;
    inset: 0;
    cursor: pointer
}

.ent-pill .face {
    display: flex;
    align-items: center;
    gap: 9px;
    border: 1.5px solid var(--adm-line);
    border-radius: 10px;
    padding: 13px 15px;
    font-size: 14px;
    font-weight: 600;
    background: #fff;
    transition: border-color .15s, background .15s
}

.ent-pill .face small {
    color: var(--adm-muted);
    font-weight: 500;
    margin-inline-start: auto
}

.ent-pill .face i {
    color: var(--adm-accent)
}

.ent-pill input:checked+.face {
    border-color: var(--adm-primary);
    background: var(--adm-primary-050);
    box-shadow: inset 0 0 0 1px var(--adm-primary)
}

.ent-pill input:focus-visible+.face {
    box-shadow: 0 0 0 3px rgba(var(--adm-accent-rgb), .25)
}

/* ── OTP boxes ──────────────────────────────────────────────────────────── */
.ent-otp-auto {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    opacity: 0
}

.ent-otp-boxes {
    display: flex;
    gap: 8px;
    justify-content: center;
    margin: 16px 0 4px
}

.ent-otp-box {
    width: 46px;
    height: 56px;
    text-align: center;
    font-size: 22px;
    font-weight: 700;
    border: 1.5px solid var(--adm-line);
    border-radius: 10px;
    background: #fff;
    color: var(--adm-ink)
}

.ent-otp-box:focus {
    outline: none;
    border-color: var(--adm-accent-bright);
    box-shadow: 0 0 0 3px rgba(var(--adm-accent-rgb), .2)
}

.ent-otp-box.is-filled {
    border-color: var(--adm-primary)
}

@media (max-width: 420px) {
    .ent-otp-box {
        width: 40px;
        height: 50px;
        font-size: 19px
    }
}

.ent-recovery {
    display: flex;
    gap: 16px;
    justify-content: center;
    margin-top: 14px;
    flex-wrap: wrap
}

/* ── Messages ───────────────────────────────────────────────────────────── */
.ent-msg {
    margin-top: 14px;
    font-size: 13.5px;
    min-height: 1.2em
}

.ent-msg.is-err {
    color: var(--adm-danger)
}

.ent-msg.is-ok {
    color: var(--adm-success)
}

/* ── Success / handoff ──────────────────────────────────────────────────── */
.ent-success {
    text-align: center;
    padding: 40px 24px 44px
}

.ent-tick {
    font-size: 52px;
    color: var(--adm-success);
    margin-bottom: 10px
}

.ent-spin {
    margin: 18px auto 0;
    width: 30px;
    height: 30px
}

.ent-spin span {
    display: block;
    width: 100%;
    height: 100%;
    border: 3px solid var(--adm-line);
    border-top-color: var(--adm-primary);
    border-radius: 50%;
    animation: entSpin .8s linear infinite
}

@keyframes entSpin {
    to {
        transform: rotate(360deg)
    }
}

@media (prefers-reduced-motion: reduce) {
    .ent-spin span {
        animation-duration: 2s
    }
}

/* ── Mini-form section heading ────────────────────────────────────────────
   The same EN-left / AR-right split as .ent-label, which is why the two spans
   collided without it — but heavier and with a rule beneath, because this
   separates BLOCKS rather than naming a field. */
.ent-minihead {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    margin: 22px 0 12px;
    padding-bottom: 7px;
    border-bottom: 1px solid var(--adm-line);
    font-size: 15px;
    font-weight: 800;
    color: var(--adm-primary);
}

.ent-minihead .ar {
    font-weight: 700;
    font-size: 14px;
    color: var(--adm-accent);
}

/* The first heading in a block sits under the lead paragraph, so it does not
   need the full separation the ones after it do. */
.ent-newperson .ent-minihead:first-of-type {
    margin-top: 14px
}

/* ── A label that asks rather than names ──────────────────────────────────
   "You are the" told the parent nothing. This is for a question, so it wraps
   instead of truncating, and the "(Please select)" hint is quieter than the
   question itself without disappearing. */
.ent-label--ask {
    align-items: flex-start;
    gap: 16px;
    flex-wrap: wrap;
}

.ent-label--ask .en,
.ent-label--ask .ar {
    line-height: 1.5
}

.ent-label--ask em {
    font-style: normal;
    font-weight: 600;
    opacity: .72;
}

/* ── Inline radio set ─────────────────────────────────────────────────────
   The default .ent-radioset stretches its pills to fill the row, which is right
   for the channel picker (one pill per line, each a destination) and wrong for
   a two-way choice: at full width a pill stops looking like something to press.
   Here they take their content's width and sit side by side. */
.ent-radioset--inline {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: flex-start;
}

.ent-radioset--inline .ent-pill {
    flex: 0 0 auto
}

.ent-radioset--inline .ent-pill .face {
    padding-inline: 22px;
    white-space: nowrap;
}

/* Narrow screens: let them fill the row rather than crowd. */
@media (max-width: 480px) {
    .ent-radioset--inline .ent-pill {
        flex: 1 1 100%
    }

    .ent-radioset--inline .ent-pill .face {
        justify-content: center
    }
}

/* ── Duplicate-child notice ───────────────────────────────────────────────
   Shown when check_child finds an existing record for this child under a parent
   of this name. ADVISORY, not an error — amber rather than red, sitting in the
   flow rather than interrupting it. There is deliberately no dismiss button and
   the submit stays enabled: the parent is being told something, not stopped.
   Only they can say whether the record we found is theirs. */
.ent-dupwarn {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    margin: 18px 0 4px;
    padding: 14px 16px;
    border: 1px solid var(--adm-line);
    border-inline-start: 4px solid var(--adm-accent);
    border-radius: 8px;
    background: var(--adm-well);
    color: var(--adm-body);
    font-size: 13.5px;
    line-height: 1.6;
}

.ent-dupwarn>i {
    flex: 0 0 auto;
    margin-top: 2px;
    font-size: 16px;
    color: var(--adm-accent);
}

.ent-dupwarn__body {
    flex: 1 1 auto
}

.ent-dupwarn__body p {
    margin: 0 0 8px
}

.ent-dupwarn__body p:last-child {
    margin-bottom: 0
}

.ent-dupwarn__body b {
    font-weight: 700;
    color: var(--adm-primary);
}

/* The Arabic paragraph mirrors the English one; it reads right-to-left and
   should sit against that edge rather than trailing the English. */
.ent-dupwarn__body p[dir="rtl"] {
    text-align: right;
    color: var(--adm-muted);
}

/* A masked parent name inside the duplicate notice. On Saint Mary these are
   Arabic sitting in an English sentence, so the span declares its own direction
   (set by the JS from CAT_CFG.parentNameScript — a per-parish fact, not a
   guess) and ISOLATES it, which is what stops the surrounding punctuation
   reordering. Cairo explicitly: the notice inherits the body font, and an
   Arabic run in a Latin face falls back to whatever the system happens to
   have. */
.ent-dupname {
    font-family: "Cairo", system-ui, -apple-system, "Segoe UI", sans-serif;
    unicode-bidi: isolate;
    font-weight: 700;
    color: var(--adm-primary);
    white-space: nowrap;
}

/* The birth-year rule on the mini-form. .ent-hint is for asides; this sentence
   is the eligibility rule itself — a family outside it cannot register — so it
   carries the accent and the weight of something to be read rather than
   skimmed. */
.ent-hint--rule {
    color: var(--adm-body);
    font-size: 13.5px;
    margin: 10px 0 0;
}

.ent-hint--rule b {
    font-weight: 800;
    color: var(--adm-accent);
}

/* An input that holds an Arabic name — the parent-name fields on a parish whose
   parent_name_script is 'arabic'. dir="rtl" on the element handles the caret and
   the reading order; this handles the face and the alignment, which it does
   not. */
.ent-affix .form-control.ent-rtl-name {
    font-family: "Cairo", system-ui, -apple-system, "Segoe UI", sans-serif;
    text-align: right;
}

.ent-affix .form-control.ent-rtl-name::placeholder {
    text-align: right;
}