/* =============================================================================
   celeb-wall.css — _celeb_tools, _celeb_wall, _celeb_overlay
   The celebrity list, 10.1 on the page list. Built 2026-09-30.

   PAGE-SCOPED, like book3d.css: one link, on celebrities.html only. Nothing
   here is wanted anywhere else, and a wall of photos is not a block another
   page will borrow.

   Every value goes through tokens.css. The only numbers that do not are the
   photo sizes, which are configuration in the markup (data-sizes).
   ============================================================================= */
/* ==========================================================================
   _celeb_tools
   ========================================================================== */
.celeb-tools {
    padding-top: var(--space-6);
    padding-bottom: var(--space-6);

    /* Above the wall, so that when a tool opens the wall slides down from
       UNDER this section (see slideWall in celeb-wall.js). Its ground is
       opaque. */
    position: relative;
    z-index: 2;
}

/* The page is not to be moved to keep the wall still while a tool opens: the
   wall is meant to move. (Scroll anchoring would cancel the slide.) */
.celeb-explorer {
    overflow-anchor: none;
}

/* ---- the bar: search, order, size ----
   Sticks while the wall scrolls under it. Full width and drawn on the
   section's own darkest blue with a blur, so the faces passing beneath read
   as passing beneath, not as colliding with it. */
.celeb-bar {
    position: sticky;
    top: 0;
    z-index: 60;

    /* margin-bottom: var(--space-6) */
    background-color: var(--c-blue-900);

    /* backdrop-filter: blur(10px) REMOVED 2026-10-02. The ground above is
       opaque, so the blur never showed, but the browser still blurred the
       wall under the bar on every scrolled frame. */
    border-bottom: 1px dotted var(--c-white-25);
    border-top: 1px dotted var(--c-white-25);
}

.celeb-bar__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3) var(--space-4);
    max-width: var(--container-w);
    margin: 0 auto;
    padding: var(--space-6) .75em;
}

.celeb-search {
    flex: 1 1 16rem;
}

/* Not .w-input: that field is cream and belongs to forms, the light set.
   A search box over a dark page is part of the page, so it is a line on
   dark, like the bar it sits in. */
.celeb-search__input {
    width: 100%;
    padding: var(--space-2) var(--space-4) var(--space-2) 3rem;
    border: 1px solid var(--c-white-55);
    border-radius: var(--radius-pill);
    background-color: transparent;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' fill='none' stroke='%23fff' stroke-width='1.5' viewBox='0 0 24 24'%3E%3Ccircle cx='10.5' cy='10.5' r='6.5'/%3E%3Cpath d='m15.5 15.5 5 5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: var(--space-4) center;
    color: var(--c-white);
    font-family: var(--font-body);
    font-size: var(--fs-md);
    line-height: var(--lh-loose);
    background-size: 1.5rem;
}

.celeb-search__input::placeholder {
    color: var(--c-white-55);
}

/* The clear button. The browser's own is a small dark grey cross, nearly
   invisible on this ground (Zlatan, 2026-10-01): replaced by a white one,
   20px, in a 1.75rem target, orange on hover. WebKit and Blink only;
   Firefox draws none, and Escape still clears there. */
.celeb-search__input::-webkit-search-cancel-button {
    -webkit-appearance: none;
    appearance: none;
    width: 1.75rem;
    height: 1.75rem;
    margin-right: calc(var(--space-2) * -1);
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='none' stroke='%23fff' stroke-width='1.75' viewBox='0 0 24 24'%3E%3Cpath d='M6 6l12 12M18 6 6 18'/%3E%3C/svg%3E") no-repeat center / 1.25rem;
    opacity: .85;
    cursor: pointer;
}

.celeb-search__input::-webkit-search-cancel-button:hover {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='none' stroke='%23ffa257' stroke-width='1.75' viewBox='0 0 24 24'%3E%3Cpath d='M6 6l12 12M18 6 6 18'/%3E%3C/svg%3E");
    opacity: 1;
}

.celeb-search__input:focus {
    outline: none;
    border-color: var(--c-orange);
    background-color: var(--c-blue-900);
    color: var(--c-white-soft);
}

/* ---- toggles: one look for every on/off control on the page ----
   Order, the three bodies, the months. Outline pill on dark; on = orange
   fill. aria-pressed is the state, so the look and what a screen reader
   hears cannot disagree. */
.celeb-order,
.celeb-bodies {
    display: inline-flex;
    gap: var(--space-2);
}

.celeb-toggle {
    padding: var(--space-1) var(--space-4);
    border: 1px solid var(--c-white-55);
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--c-white-85);
    font-family: var(--font-body);
    font-size: var(--fs-base);
    line-height: var(--lh-loose);
    cursor: pointer;
    transition: background-color var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}

.celeb-toggle[aria-pressed="true"] {
    border-color: var(--c-orange);
    background-color: var(--c-orange);
    color: var(--c-blue-950);
}

@media (hover: hover) {
    .celeb-toggle:hover {
        border-color: var(--c-orange);
        color: var(--c-white);
    }

    .celeb-toggle[aria-pressed="true"]:hover {
        color: var(--c-blue-950);
    }
}

.celeb-toggle .astro-glyph {
    font-size: var(--fs-lg);
    vertical-align: -2px;
}

/* A–Z / Z–A: one button, two labels; data-dir says which shows. */
.celeb-order__az [data-dir-label] {
    display: none;
}

.celeb-order__az[data-dir="az"] [data-dir-label="az"],
.celeb-order__az[data-dir="za"] [data-dir-label="za"] {
    display: inline;
}

/* ---- size: four columns that grow ----
   Each button is a bar of the height it stands for (25/50/75/100% of the
   control's height), bottom-aligned, so the four read as a bar chart
   climbing to the right. On = orange, like every chosen control here. */
.celeb-size {
    position: relative;
    display: inline-flex;
    align-items: flex-end;
    gap: var(--space-1);
    height: 2.25rem;
}

.celeb-size__option {
    display: flex;
    align-items: flex-end;
    width: 1.55rem;
    height: 100%;
    padding: 0 .1rem;
    border: 0;
    background: none;
    cursor: pointer;
}

.celeb-size__bar {
    display: block;
    width: 100%;
    border: 1.5px solid var(--c-white-55);
    background-color: transparent;
    transition: background-color var(--transition-fast), border-color var(--transition-fast);
}

.celeb-size__option:nth-of-type(1) .celeb-size__bar {
    height: 25%;
}

.celeb-size__option:nth-of-type(2) .celeb-size__bar {
    height: 50%;
}

.celeb-size__option:nth-of-type(3) .celeb-size__bar {
    height: 75%;
}

.celeb-size__option:nth-of-type(4) .celeb-size__bar {
    height: 100%;
}

/* The info bubble: on hover, and when a size button has keyboard focus.
   Never the only way to learn it — the bars draw what they do. */
@media (hover: hover) {
    .celeb-size:hover .celeb-size__tip {
        opacity: 1;
        transform: translate(-50%, 0);
    }
}

.celeb-size:focus-within .celeb-size__tip {
    opacity: 1;
    transform: translate(-50%, 0);
}

.celeb-size__option[aria-pressed="true"] .celeb-size__bar {
    border-color: var(--c-orange);
    background-color: var(--c-orange);
}

@media (hover: hover) {
    .celeb-size__option:hover .celeb-size__bar {
        border-color: var(--c-orange);
    }
}

.celeb-size__option:focus-visible {
    outline: 2px solid var(--c-orange);
    outline-offset: 2px;
}

/* Phone: search takes the whole first row, order and size share the second. */
@media (max-width: 767px) {
    .celeb-search {
        flex-basis: 100%;
    }

    .celeb-order {
        margin-right: auto;
    }
}

/* ---- the three tools ---- */
.celeb-tabs {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-2) var(--space-6);
    margin-bottom: var(--space-4);
}

/* A tab is a word with an orange underline when open — the .section-label
   dotted line, made solid when it is chosen. */
.celeb-tab {
    padding: var(--space-2) var(--space-1);
    border: 0;
    border-bottom: 2px dotted var(--c-orange-50);
    background: none;
    color: var(--c-white-85);
    font-family: var(--font-body);
    font-size: var(--fs-md);
    font-weight: var(--fw-semibold);
    letter-spacing: 1px;
    text-transform: uppercase;
    cursor: pointer;
}

.celeb-tab[aria-expanded="true"] {
    border-bottom-style: solid;
    border-bottom-color: var(--c-orange);
    color: var(--c-orange);
}

/* A small orange dot on a folded tab whose filter is still on, so the reader
   knows where the chip came from. Set by the script as data-active. */
.celeb-tab[data-active]::after {
    content: "";
    display: inline-block;
    width: 6px;
    height: 6px;
    margin-left: var(--space-2);
    border-radius: 50%;
    background-color: var(--c-orange);
    vertical-align: middle;
}

@media (max-width: 599px) {
    .celeb-tabs {
        flex-wrap: nowrap;
        gap: var(--space-3);
    }

    .celeb-tab {
        font-size: var(--fs-sm);
        letter-spacing: .5px;
        white-space: nowrap;
    }
}

@media (hover: hover) {
    .celeb-tab:hover {
        color: var(--c-white);
    }
}

.celeb-tool {
    padding: var(--space-4) 0 var(--space-2);
    text-align: center;

    /* padding-bottom: var(--space-6) */
}

.celeb-tool[hidden] {
    display: none;
}

.celeb-tool__lead {
    /* max-width: 36em */
    margin: 0 auto var(--space-4);
    color: var(--c-white-75);
}

.celeb-tool__label {
    display: block;
    margin: var(--space-4) 0 var(--space-2);
    font-size: var(--fs-xs);
    font-weight: var(--fw-bold);
    letter-spacing: 2px;
    text-transform: uppercase;
    color: var(--c-orange);
}

/* ---- By sign: twelve glyphs ----
   Six across on a phone (two rows), twelve from 768. The count under each
   name is how many people that sign would leave on the wall, given every
   other filter. A sign that would leave nobody is dimmed, not hidden: the
   zodiac keeps its shape. */
.celeb-signs {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: var(--space-2);
    margin: 0;
    padding: 0;
    list-style: none;
}

@media (min-width: 768px) {
    .celeb-signs {
        grid-template-columns: repeat(12, minmax(0, 1fr));
    }
}

.celeb-sign {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100%;
    padding: var(--space-2) 0;
    border: 1px solid transparent;
    border-radius: var(--radius);
    background: transparent;
    color: var(--c-white-85);
    font-family: var(--font-body);
    cursor: pointer;
    transition: background-color var(--transition-fast), color var(--transition-fast), opacity var(--transition-fast), transform var(--transition-fast);
    position: relative;
}

.celeb-sign__glyph {
    font-size: var(--fs-3xl);
}

.celeb-sign__name {
    font-size: var(--fs-xs);
    letter-spacing: .5px;
}

.celeb-sign__count {
    font-size: var(--fs-xs);
    color: var(--c-white-55);
    min-height: 1.2em;
    position: absolute;
    top: 0;
    right: 0;
    background-color: var(--c-blue-850);
    border-radius: 50%;
    padding: 1px;
    height: 18px;
    width: 18px;
}

/* Dealt again when the body changes (Sun / Moon / Rising): each sign turns
   in on its own, 25ms after the one before (--i from the script). */
.celeb-signs.is-dealing .celeb-sign {
    animation: celeb-sign-deal .32s cubic-bezier(.2, .7, .2, 1) calc(var(--i, 0) * 25ms) backwards;
}

@keyframes celeb-sign-deal {
    from {
        opacity: 0;
        transform: rotateY(90deg) scale(.85);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

.celeb-sign[data-empty] {
    opacity: .3;
}

.celeb-sign[aria-pressed="true"] {
    border-color: var(--c-orange);
    background-color: var(--c-orange);
    color: var(--c-blue-950);
}

.celeb-sign[aria-pressed="true"] .celeb-sign__count {
    /* color: var(--c-blue-900) */
}

@media (hover: hover) {
    .celeb-sign:hover {
        border-color: var(--c-orange-50);
        transform: translateY(-2px);
    }
}

/* ---- By birthday ---- */
/* The decades: a bar chart of the catalogue that is also the control. Each
   bar is a button; its height (--h, set by the script) is its share of the
   tallest decade. */
.celeb-decades {
    display: flex;
    align-items: flex-end;
    justify-content: center;
    gap: 3px;
    height: 7rem;
    margin-bottom: 2.75rem;
    margin-top: 1rem;
}

.celeb-decade {
    position: relative;
    flex: 0 1 2.5rem;
    min-width: 0;
    height: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}

.celeb-decade__bar {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: calc(var(--h, 0) * 100%);
    min-height: 3px;
    background-color: var(--c-blue-500);
    transition: background-color var(--transition-fast), height .25s ease;
}

.celeb-decade__year {
    position: absolute;
    left: 50%;
    bottom: -1.4rem;
    transform: translateX(-50%) rotate(-45deg);
    transform-origin: center;
    font-size: var(--fs-xs);
    color: var(--c-white-55);
    white-space: nowrap;
}

/* The full catalogue reaches back to the 1770s, so on a phone the bars get
   thin and every other year label goes: the bars keep their places, the
   labels stop colliding. */
@media (max-width: 599px) {
    .celeb-decade:nth-child(even) .celeb-decade__year {
        display: none;
    }
}

.celeb-decade[aria-pressed="true"] .celeb-decade__bar {
    background-color: var(--c-orange);
}

.celeb-decade[aria-pressed="true"] .celeb-decade__year {
    color: var(--c-orange);
}

.celeb-decade[data-empty] {
    opacity: .3;
}

@media (hover: hover) {
    .celeb-decade:hover .celeb-decade__bar {
        background-color: var(--c-orange-50);
    }
}

/* The day and month selects are the birth data form's own .w-select — the
   light field on a dark tool, like the chart form's card. The button sits
   level with them. */
.celeb-day {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: center;
    gap: var(--space-4);
}

.celeb-day .celeb-tool__label {
    margin-top: 0;
}

.celeb-day .w-line {
    justify-content: center;
}

/* Day and month, drawn as the "Born today" button beside them (Zlatan,
   2026-10-01): .button.outline.small-button's border, radius, padding and
   type, with the house's one down chevron. Native selects underneath, so a
   phone still opens its own picker. */
.celeb-select {
    width: 6.5rem;
    min-height: 0;
    margin: 0;
    padding: var(--space-2) 2.25rem var(--space-2) var(--space-4);
    border: 2px solid var(--c-white-75);
    border-radius: var(--radius);
    background: transparent url('../img/icons/chevron-down-white.svg') no-repeat right var(--space-3) center / 12px;
    color: var(--c-white-75);
    font-family: var(--font-body);
    font-size: var(--fs-md);
    letter-spacing: 1px;
    line-height: var(--lh-loose);
    appearance: none;
    -webkit-appearance: none;
    cursor: pointer;
    transition: background-color var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}

.celeb-select--wide {
    width: 10.5rem;
}

.celeb-select option {
    color: var(--c-text);
}

@media (hover: hover) {
    .celeb-select:hover {
        border-color: var(--c-green);
        background-color: var(--c-green);
        color: var(--c-white);
    }
}

.celeb-select:focus-visible {
    outline: 2px solid var(--c-orange);
    outline-offset: 2px;
}

/* A chosen day or month reads as chosen: orange, like every pressed control
   on the page. */
.celeb-select:has(option:checked:not([value=""])) {
    border-color: var(--c-orange);
    color: var(--c-orange);
}

.celeb-day .button {
    min-height: var(--space-12);
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

/* ---- Your star twins ---- */
.celeb-twin-charts {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-2);
    margin-bottom: var(--space-4);
}

.celeb-twin-chart {
    padding: var(--space-2) var(--space-4);
    border: 1px solid var(--c-white-55);
    border-radius: var(--radius);
    background: transparent;
    color: var(--c-white-85);
    font-family: var(--font-body);
    cursor: pointer;
}

.celeb-twin-chart[aria-pressed="true"] {
    border-color: var(--c-orange);
    color: var(--c-white);
    box-shadow: inset 0 0 0 1px var(--c-orange);
}

.celeb-twin-one {
    margin-bottom: var(--space-6);
    color: var(--c-orange);

    /* border-top: 1px dotted var(--c-orange) */
    /* border-bottom: 1px dotted var(--c-orange) */
    /* padding: var(--space-3) 0 */
}

.celeb-twin-one .saved-chart__label {
    display: block;
    color: var(--c-white-75);
}

.celeb-twin-signs {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: var(--space-3);
}

/* The chart-signs cards, on dark and pressable: off = outline, on = the
   orange of every other chosen control on the page. */
.celeb-twin-sign {
    display: flex;
    flex-direction: column;
    align-items: center;
    flex: 0 1 10rem;
    padding: var(--space-3) var(--space-2);
    border: 1px solid var(--c-white-55);
    border-radius: var(--radius);
    background: transparent;
    color: var(--c-white-85);
    font-family: var(--font-body);
    cursor: pointer;
    transition: background-color var(--transition-fast), color var(--transition-fast);
}

.celeb-twin-sign__label {
    font-size: var(--fs-xs);
    font-weight: var(--fw-bold);
    letter-spacing: 1px;
    text-transform: uppercase;
}

.celeb-twin-sign__value {
    white-space: nowrap;
    font-family: var(--font-heading);
    font-size: var(--fs-xl);
    line-height: var(--lh-tight);
}

.celeb-twin-sign__value .astro-glyph {
    font-size: var(--fs-lg);
}

/* The count as a corner badge, the same as the twelve signs' counts
   (.celeb-sign__count, Zlatan's 2026-10-01 pass): a small round dot at the
   top right of the card. Asked for by Zlatan the same day. */
.celeb-twin-sign {
    position: relative;
}

.celeb-sign__count,
.celeb-twin-sign__count {
    display: flex;
    align-items: center;
    justify-content: center;
}

.celeb-twin-sign__count {
    position: absolute;
    top: 0.15rem;
    right: 0.15rem;
    width: 18px;
    height: 18px;
    padding: 1px;
    border-radius: 50%;
    background-color: var(--c-blue-850);
    color: var(--c-white-55);
    font-size: var(--fs-xs);
    line-height: 1;
}

.celeb-twin-sign[aria-pressed="true"] {
    border-color: var(--c-orange);
    background-color: var(--c-orange);
    color: var(--c-blue-950);
}

/* ---- chips ---- */
.celeb-chips {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    margin-top: var(--space-4);
    margin-bottom: var(--space-3);
}

.celeb-chips[hidden] {
    display: none;
}

.celeb-chips__list {
    display: contents;
}

.celeb-chips__list > li {
    list-style: none;
}

/* The whole chip is the button (Zlatan, 2026-10-01). The x is drawn inside
   it and turns orange with the chip's border on hover. */
.celeb-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-1) var(--space-1) var(--space-1) var(--space-3);
    border: 1px solid transparent;
    border-radius: var(--radius-pill);
    background-color: var(--c-blue-800);
    color: var(--c-white);
    font-family: var(--font-body);
    font-size: var(--fs-sm);
    cursor: pointer;
    animation: celeb-chip-enter .15s ease-out backwards;
    transition: border-color var(--transition-fast), background-color var(--transition-fast);
}

.celeb-chip .astro-glyph {
    font-size: var(--fs-base);
    color: var(--c-orange);
}

.celeb-chip__x {
    width: 1.5rem;
    height: 1.5rem;
    --close-mark: .625rem;
    --close-weight: 1.25px;
}

@media (hover: hover) {
    .celeb-chip:hover {
        border-color: var(--c-orange);
        background-color: var(--c-blue-850);
    }

    .celeb-chip:hover .celeb-chip__x {
        color: var(--c-orange);
    }
}

.celeb-chip:focus-visible {
    outline: 2px solid var(--c-orange);
    outline-offset: 2px;
}

@keyframes celeb-chip-enter {
    from {
        opacity: 0;
        transform: scale(.8);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

.celeb-chips__clear {
    padding: var(--space-1) var(--space-2);
    border: 0;
    background: none;
    color: var(--c-orange);
    font-family: var(--font-body);
    font-size: var(--fs-sm);
    text-decoration: underline dotted;
    text-underline-offset: 3px;
    cursor: pointer;
}

/* ==========================================================================
   _celeb_wall
   ========================================================================== */
.celeb-wall-section {
    background-color: var(--c-blue-950);
}

/* THE WALL. No gap, no margin, no radius: one picture made of faces.

   COLUMNS, by screen width and by data-size (the four size buttons; 2 is
   the page's default). Zlatan, 2026-10-16: by default 3 columns under
   768px, 4 under 900, 5 under 1200, 6 from 1200 (was 3/4/5/6 at 540/768/
   1200 since 2026-09-30) — the other sizes step one or two columns either
   side of that:

                   size 1   size 2   size 3   size 4
       < 768          4        3        2        1
       768–899        6        4        3        2
       900–1199       7        5        4        3
       1200 +         8        6        4        3

   Fixed counts at every width, so every screen gets the layout it was
   drawn for; the photos grow with the screen instead. 768 and 900 are
   canonical breakpoints; 1200 is for this wall only (house style lists
   the special cases). */
.celeb-wall {
    --celeb-cols: 3;
    display: grid;
    grid-template-columns: repeat(var(--celeb-cols), minmax(0, 1fr));
    gap: 0;
    margin: 0;
    padding: 0;
    list-style: none;

    /* Its own layer: when the panel above opens and pushes the wall down, the
       finished picture of the wall is moved, not drawn again. */
    will-change: transform;
}

.celeb-wall[data-size="1"] {
    --celeb-cols: 4;
}

.celeb-wall[data-size="3"] {
    --celeb-cols: 2;
}

.celeb-wall[data-size="4"] {
    --celeb-cols: 1;
}

@media (min-width: 768px) {
    .celeb-wall {
        --celeb-cols: 4;
    }

    .celeb-wall[data-size="1"] {
        --celeb-cols: 6;
    }

    .celeb-wall[data-size="3"] {
        --celeb-cols: 3;
    }

    .celeb-wall[data-size="4"] {
        --celeb-cols: 2;
    }
}

@media (min-width: 900px) {
    .celeb-wall {
        --celeb-cols: 5;
    }

    .celeb-wall[data-size="1"] {
        --celeb-cols: 7;
    }

    .celeb-wall[data-size="3"] {
        --celeb-cols: 4;
    }

    .celeb-wall[data-size="4"] {
        --celeb-cols: 3;
    }
}

@media (min-width: 1200px) {
    .celeb-wall {
        --celeb-cols: 6;
    }

    .celeb-wall[data-size="1"] {
        --celeb-cols: 8;
    }

    .celeb-wall[data-size="3"] {
        --celeb-cols: 4;
    }

    .celeb-wall[data-size="4"] {
        --celeb-cols: 3;
    }
}

.celeb-wall > li {
    margin: 0;

    /* MADE LIGHT FOR SEVERAL HUNDRED CARDS (2026-10-02, Zlatan: the tool
       panel opened "clumsy", and the database now has 700+ charts).

       Measured, not guessed: laying out the wall costs about 7 microseconds a
       card on a fast machine (1ms at 125 cards, 8ms at 875), and every card
       also carries a grayscale filter and a blended tint, which the browser
       repaints whenever the wall moves — and the wall moves on every frame of
       the panel's height animation.

       1. The li is square itself (aspect-ratio), so its height never depends
          on what is inside it, and
       2. content-visibility: auto lets the browser skip drawing and
          laying out the inside of every card that is off screen. The size
          stays right because of (1), so nothing jumps and the FLIP
          measurements stay true. */
    aspect-ratio: 1;
    content-visibility: auto;
    contain-intrinsic-size: auto 12rem;
}

.celeb-wall > li[hidden] {
    display: none;
}

/* A card is its photo. Square, everything on top of it. container-type lets
   the words scale with the card rather than with the screen, so the size
   control changes the type along with the photo. */
.celeb-card {
    position: relative;
    display: block;
    aspect-ratio: 1;
    overflow: clip;
    container-type: inline-size;
    background-color: var(--c-blue-900);
    color: var(--c-white);
    text-decoration: none;
}

.celeb-card__photo {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform .35s cubic-bezier(.2, .7, .2, 1), filter .2s ease;
}

/* The scrim that the name sits on: dark blue from the bottom, gone by the
   middle. Stronger on hover, when the signs arrive too. */
.celeb-card::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    background-image: linear-gradient(to top, var(--c-blue-950) 0%, var(--c-blue-950-80) 18%, transparent 55%);
    transition: opacity var(--transition-fast);
    pointer-events: none;
}

.celeb-card__text {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 3;
    padding: 0 7cqi 6cqi;
    text-align: left;
}

.celeb-card__name {
    transition: color var(--transition-fast);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: clip;
    font-family: var(--font-heading-fat);
    font-size: clamp(var(--fs-xs), 10cqi, var(--fs-2xl));
    line-height: var(--lh-tiny);
    text-shadow: var(--shadow-text);
}

.celeb-card__date {
    display: block;
    margin-top: 2cqi;
    font-size: clamp(var(--fs-xs), 7cqi, var(--fs-base));
    line-height: var(--lh-tight);
    color: var(--c-white-85);
}

/* Sun, Moon and Rising as glyphs, top left. Shown on hover (desktop), on
   keyboard focus, always on the two largest sizes, and always when the sky
   twins are on — then the shared ones turn orange. The overlay says the
   same in words, so this is never the only way to learn it (2026-09-08). */
.celeb-card__signs {
    position: absolute;
    top: 5cqi;
    left: 6cqi;
    z-index: 3;
    display: flex;
    gap: 4cqi;
    font-size: clamp(.75rem, 9cqi, var(--fs-md));
    text-shadow: var(--shadow-text);
    opacity: 0;
    transform: translateY(-4px);
    transition: opacity var(--transition-fast), transform var(--transition-fast);
}

.celeb-card__signs > span {
    padding: 1cqi 2cqi;
    border-radius: var(--radius-sm);
    background-color: var(--c-blue-950-80);
    letter-spacing: 5px;
}

.celeb-card:focus-visible {
    outline: 3px solid var(--c-orange);
    outline-offset: -3px;
}

.celeb-card:focus-visible .celeb-card__signs,
.celeb-wall[data-twins] .celeb-card__signs {
    opacity: 1;
    transform: none;
}

@media (hover: hover) {
    .celeb-card:hover .celeb-card__photo {
        transform: scale(1.08);
    }

    .celeb-card:hover .celeb-card__name {
        color: var(--c-orange);
    }

    .celeb-card:hover .celeb-card__signs {
        opacity: 1;
        transform: none;
    }
}

@container (min-width: 250px) {
    .celeb-card__signs {
        opacity: 1;
        transform: none;
    }
}

/* Below 125px there is room for a name and nothing else. The date is in the
   overlay one tap away. */
@container (max-width: 124px) {
    .celeb-card__date {
        display: none;
    }
}

/* Star twins: the shared signs light up, the others fade back. */
.celeb-wall[data-twins] .celeb-card__signs > span {
    opacity: .45;
}

.celeb-card[data-match~="sun"] [data-body="sun"],
.celeb-card[data-match~="moon"] [data-body="moon"],
.celeb-card[data-match~="asc"] [data-body="asc"] {
    opacity: 1 !important;
    background-color: var(--c-orange);
    color: var(--c-blue-950);
    text-shadow: none;
}

/* PREVIEW OF ZLATAN'S DUOTONE, 2026-09-30. He will re-make the photos,
   "most likely in dark blue duotone". This is the same look done in CSS,
   so the wall can be judged in it now, and it answers a question for later:
   if the CSS version is good enough, the photos need no second edit, and a
   new celebrity needs only a photo.
   Grayscale first, then the blue laid over it with `color`, which keeps each
   pixel's lightness and takes the blue's hue — dark stays navy, light goes
   pale blue. On hover the face comes back in colour: the fun half.
   REMOVE the class from the <ul> to see the photos as they are. */
.celeb-wall--duotone .celeb-card__photo {
    filter: grayscale(1) contrast(1.1);
}

.celeb-wall--duotone .celeb-card::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    background-color: var(--c-blue-800);
    mix-blend-mode: color;
    transition: opacity .2s ease;
    pointer-events: none;
}

@media (hover: hover) {
    .celeb-wall--duotone .celeb-card:hover .celeb-card__photo {
        filter: none;
    }

    .celeb-wall--duotone .celeb-card:hover::before {
        opacity: 0;
    }
}

.celeb-wall--duotone .celeb-card:focus-visible .celeb-card__photo {
    filter: none;
}

.celeb-wall--duotone .celeb-card:focus-visible::before {
    opacity: 0;
}

/* A card arriving on the wall (after a filter lets it back) grows in. */
.celeb-wall > li.is-entering .celeb-card {
    animation: celeb-card-enter .28s cubic-bezier(.2, .7, .2, 1) backwards;
}

@keyframes celeb-card-enter {
    from {
        opacity: 0;
        transform: scale(.6);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

.celeb-empty {
    padding: var(--space-16) var(--space-4);
    text-align: center;
    color: var(--c-white-75);
}

.celeb-empty[hidden] {
    display: none;
}

/* ==========================================================================
   _celeb_overlay
   Redesigned 2026-09-30 (Zlatan: "make a smaller overlay, so we can see a
   bit of page. Make it in a blue design"). A centred dark-blue panel; the
   wall shows through a dimmed, blurred backdrop around it.

   Desktop: the photo left, full height of the panel, the facts right.
   Phone: the photo on top, cropped to a band so the signs and the button
   are on the first screen, the facts below; the arrows move inside.
   ========================================================================== */
/* The page behind: dimmed to the site's night blue and softened, not hidden
   — the reader should still see where on the wall they were. */
.celeb-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 260;
    background-color: var(--c-blue-950-80);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}

.celeb-backdrop.open {
    display: block;
    animation: celeb-fade-in .3s ease-out backwards;
}

/* The panel is a full-screen positioning layer that centres the box. It is
   transparent; a click on it (not on the box) closes, like the backdrop. */
.celeb-panel {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 270;
    padding: var(--space-6) var(--space-4);
    overflow-y: auto;
    overscroll-behavior: contain;
}

.celeb-panel.open {
    display: flex;
    align-items: center;
    justify-content: center;
}

.celeb-panel:focus {
    outline: none;
}

/* THE BOX. 880px: a third narrower than the 940 container, so the wall
   shows on both sides of a laptop screen. Ground = the section blues, a
   drawn 7px seam on top (house style, 2026-09-17), square corners, and the
   deep shadow that lifts it off the page. */
.celeb-panel__box {
    position: relative;
    width: 100%;
    max-width: 880px;
    margin: auto;
    background-image: var(--c-blue-gradient-900);
    border-top: 7px solid var(--c-blue-700);
    box-shadow: var(--shadow-raised);
    color: var(--c-white-85);
}

.celeb-panel.open .celeb-panel__box {
    animation: celeb-box-enter .45s cubic-bezier(.2, .7, .2, 1) backwards;
}

.celeb-panel__close {
    position: absolute;
    top: var(--space-3);
    right: var(--space-3);
    z-index: 3;
    color: var(--c-white);
}

.celeb-panel__body {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 768px) {
    .celeb-panel__body {
        grid-template-columns: minmax(0, 11fr) minmax(0, 12fr);
    }
}

/* ---- the picture ----
   In colour: the duotone belongs to the wall, and the overlay is the moment
   the face comes forward. A slow zoom-out on arrival, the photo settling. */
.celeb-panel__picture {
    position: relative;
    overflow: clip;
    background-color: var(--c-blue-950);
}

/* Desktop: the column's width, the row's height — the facts beside it set
   how tall the box is, and the photo fills it, cropped by cover. The
   minimum keeps it near square when the facts are short. */
@media (min-width: 768px) {
    .celeb-panel__picture {
        min-height: 26rem;
    }

    .celeb-panel__photo {
        position: absolute;
        inset: 0;
    }
}

@media (max-width: 767px) {
    /* A band, not a square, so the facts start on the first screen. The
       face sits in the upper half of these portraits, so the crop keeps it. */
    .celeb-panel__picture {
        aspect-ratio: 4 / 3;
    }
}

.celeb-panel__photo {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center 30%;
}

.celeb-panel.open .celeb-panel__photo {
    animation: celeb-photo-settle 1.2s cubic-bezier(.2, .7, .2, 1) backwards;
}

/* The same scrim as the wall's cards, deeper, with the name large on it. */
.celeb-panel__picture::after {
    content: "";
    position: absolute;
    inset: 0;
    background-image: linear-gradient(to top, var(--c-blue-950) 0%, var(--c-blue-950-80) 20%, transparent 55%);
    pointer-events: none;
}

.celeb-panel__caption {
    position: absolute;
    left: var(--space-6);
    right: var(--space-6);
    bottom: var(--space-6);
    z-index: 2;
}

.celeb-panel__name {
    margin: 0 0 var(--space-1);
    font-family: var(--font-heading-fat);
    font-size: var(--fs-4xl);
    line-height: var(--lh-tiny);
    color: var(--c-white);
    text-shadow: var(--shadow-text);
}

.celeb-panel__date {
    font-size: var(--fs-lg);
    color: var(--c-white-85);
}

@media (max-width: 767px) {
    .celeb-panel__name {
        font-size: var(--fs-3xl);
    }

    .celeb-panel__date {
        font-size: var(--fs-md);
    }
}

/* ---- the facts ---- */
.celeb-panel__facts {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: var(--space-8);
    text-align: left;
}

@media (max-width: 767px) {
    .celeb-panel__facts {
        padding: var(--space-6) var(--space-4) var(--space-4);
        text-align: center;
    }
}

.celeb-panel__facts .section-label span {
    padding-left: 0;
    padding-right: 0;
    font-size: var(--fs-sm);
}

.celeb-panel__born {
    margin-bottom: var(--space-6);
    font-size: var(--fs-md);
    color: var(--c-white-75);
}

/* Three signs, three dark cards: the planet small above, the sign's glyph
   large in the orange ring of the basics chapters, the sign's name under
   it. Each is a button — it closes the panel and filters the wall. */
.celeb-panel__signs {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-2);
    margin: 0 0 var(--space-2);
    padding: 0;
    list-style: none;
}

.celeb-sign-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    padding: var(--space-3) var(--space-1) var(--space-4);
    border: 0;
    border-top: 3px solid var(--c-blue-700);
    background-color: var(--c-blue-950-80);
    color: var(--c-white-85);
    font-family: var(--font-body);
    cursor: pointer;
    transition: background-color var(--transition-fast), border-color var(--transition-fast), transform var(--transition-fast);
}

.celeb-sign-card__label {
    font-size: var(--fs-xs);
    font-weight: var(--fw-bold);
    letter-spacing: 2px;
    text-transform: uppercase;
    color: var(--c-orange);
}

.celeb-sign-card__label .astro-glyph {
    font-size: var(--fs-sm);
    letter-spacing: 0;

    /* The label is uppercase, and in the icon font case is meaning: "a" is
       the Sun, "A" is Aries. The glyph keeps its own case. */
    text-transform: none;
}

.celeb-sign-card__glyph {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3.25rem;
    height: 3.25rem;
    border: 1px solid var(--c-orange-50);
    border-radius: 50%;
    font-size: var(--fs-2xl);
    color: var(--c-orange);
    transition: background-color var(--transition-fast), color var(--transition-fast);
}

.celeb-sign-card__name {
    font-family: var(--font-heading);
    font-size: var(--fs-lg);
    line-height: var(--lh-tight);
    color: var(--c-white);
}

/* "Sagittarius" in a third of a phone. */
@media (max-width: 599px) {
    .celeb-sign-card__name {
        font-size: var(--fs-md);
    }
}

@media (hover: hover) {
    .celeb-sign-card:hover {
        border-top-color: var(--c-orange);
        background-color: var(--c-blue-800);
        transform: translateY(-2px);
    }

    .celeb-sign-card:hover .celeb-sign-card__glyph {
        background-color: var(--c-orange);
        color: var(--c-blue-950);
    }
}

.celeb-sign-card:focus-visible {
    outline: 2px solid var(--c-orange);
    outline-offset: 2px;
}

.celeb-panel__hint {
    margin-bottom: var(--space-6);
    font-size: var(--fs-sm);
    color: var(--c-white-55);
}

.celeb-panel__cta {
    align-self: flex-start;
}

@media (max-width: 767px) {
    .celeb-panel__cta {
        align-self: stretch;
    }
}

.celeb-panel__count {
    margin-top: var(--space-4);
    font-size: var(--fs-sm);
    letter-spacing: 2px;
    color: var(--c-white-55);
}

/* ---- previous / next ----
   Round, outlined, white thin chevrons — the pager's look — outside the box
   on either side where there is room for them, over the blurred page. On a
   phone they drop to the bottom corners, filled, over the facts. */
.celeb-panel__nav {
    position: fixed;
    top: 50%;
    z-index: 4;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 3.25rem;
    height: 3.25rem;
    margin-top: -1.625rem;
    padding: 0;
    border: 1.5px solid var(--c-white-55);
    border-radius: 50%;
    background-color: transparent;
    cursor: pointer;
    transition: background-color var(--transition-fast), border-color var(--transition-fast);
}

.celeb-panel__nav--prev {
    left: max(var(--space-4), calc(50% - 440px - 4.5rem));
}

.celeb-panel__nav--next {
    right: max(var(--space-4), calc(50% - 440px - 4.5rem));
}

@media (hover: hover) {
    .celeb-panel__nav:hover {
        border-color: var(--c-green);
        background-color: var(--c-green);
    }
}

.celeb-panel__nav:focus-visible {
    outline: 2px solid var(--c-orange);
    outline-offset: 2px;
}

/* Below ~1040 the box leaves no room at its sides (880 + two arrows and
   their gaps), so the arrows drop to the bottom corners of the screen,
   filled so they read over whatever is behind them, and the panel keeps
   a strip free for them under the box. */
@media (max-width: 1039px) {
    .celeb-panel {
        padding-bottom: 5.5rem;
    }

    .celeb-panel__nav {
        top: auto;
        bottom: var(--space-4);
        margin-top: 0;
        border-color: var(--c-white-75);
        background-color: var(--c-blue-850);
        box-shadow: var(--shadow-tight);
    }
}

/* The change of person: the body slides a little in the direction walked.
   The script sets data-dir to -1 or 1 and restarts the animation. */
.celeb-panel__body.is-stepping[data-dir="1"] {
    animation: celeb-step-next .35s ease-out backwards;
}

.celeb-panel__body.is-stepping[data-dir="-1"] {
    animation: celeb-step-prev .35s ease-out backwards;
}

@keyframes celeb-fade-in {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

@keyframes celeb-box-enter {
    from {
        opacity: 0;
        transform: translateY(24px) scale(.97);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes celeb-photo-settle {
    from {
        transform: scale(1.12);
    }

    to {
        transform: none;
    }
}

@keyframes celeb-step-next {
    from {
        opacity: 0;
        transform: translateX(40px);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes celeb-step-prev {
    from {
        opacity: 0;
        transform: translateX(-40px);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

/* The page under an open overlay does not scroll. */
body.celeb-overlay-open {
    overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
    .celeb-chip,
    .celeb-wall > li.is-entering .celeb-card,
    .celeb-signs.is-dealing .celeb-sign,
    .celeb-chip,
    .celeb-backdrop.open,
    .celeb-panel.open .celeb-panel__box,
    .celeb-panel.open .celeb-panel__photo,
    .celeb-panel__body.is-stepping[data-dir] {
        animation: none;
    }

    .celeb-card__photo,
    .celeb-sign {
        transition: none;
    }
}

/* One row of the wall, for the chart pages' same-sign strip. Six across
   from 768px, three on a phone (two rows) — a fixed count because it is a
   row, not the wall; Rails sends up to six. */
.celeb-wall--row {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

@media (min-width: 768px) {
    .celeb-wall--row {
        grid-template-columns: repeat(6, minmax(0, 1fr));
    }
}

/* Moved from blocks.css 2026-10-01: page-scoped rules belong with the page. */
#celeb-tool-born {
    padding-top: var(--space-1);
}
