/* Generated by site/build.ts from site/page-src/wall-interactions.css. Do not edit. */
/* Wall interactions: the lens chips, the divider and the receded cards under
 * it, and the opened card. */

/* The width the page's scrollbar had, which script writes on the page's root
 * as a sheet opens and removes as it closes. The root alone reads it.
 * Registered so that it does not inherit: a value written on the root stays
 * on the root, and the browser does not restyle every element on the page
 * for it. */
@property --wall-open-scrollbar {
  syntax: "<length>";
  inherits: false;
  initial-value: 0px;
}

@layer discern.components {
  /* The lens: one row of toggle chips, never two. Where the row fits it sits
   * centered. Where it does not, it is a strip that scrolls sideways, from
   * edge to edge of the room: it fades at both ends, and a chip cut by the
   * far fade says there is more. Choosing a chip brings it to the middle.
   *
   * The strip is as wide as the screen whatever its container's width, and
   * its own padding puts the first chip back in line with the cards and
   * leaves the focus ring room. */
  .wall-lens {
    display: flex;
    flex: none;
    gap: 0.5rem;
    inline-size: 100vw;
    margin: -0.5rem calc(50% - 50vw);
    padding: 0.5rem calc(50vw - 50%);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-padding-inline: calc(50vw - 50%);
    scrollbar-width: none;
    mask-image: linear-gradient(
      90deg,
      transparent,
      oklch(0% 0 0) 1rem,
      oklch(0% 0 0) calc(100% - 1rem),
      transparent
    );
  }

  .wall-lens::-webkit-scrollbar {
    display: none;
  }

  @media (prefers-reduced-motion: no-preference) {
    .wall-lens {
      scroll-behavior: smooth;
    }
  }

  /* The bar arrives whole when the controls come alive, and so does what it
   * holds. An element shown through its parent's visibility must not
   * transition that visibility itself: under reduced motion the design system
   * gives every transition a token duration, and each level of the bar would
   * then appear a frame after the one above it. The room's stylesheet stills
   * the bar, and nothing named here has a transition of its own. */
  .wall-lens,
  .wall-lens-status,
  .wall-chip-hues,
  .wall-chip::after {
    transition: none;
  }

  /* Free space goes outside the first and last chip: a row that fits is
   * centered, and a row that does not starts at its first chip. The chips
   * are the row's only buttons; its status is not drawn. */
  .wall-chip:first-of-type {
    margin-inline-start: auto;
  }

  .wall-chip:last-of-type {
    margin-inline-end: auto;
  }

  /* A chip is a small opaque object, like a card: the wall passes under the
   * lens bar and must not show through it. The pause control is one too. */
  .wall-chip,
  .wall-pause {
    --wall-chip-surface: var(--wall-face-foot);

    position: relative;
    display: inline-flex;
    flex: none;
    align-items: center;
    gap: 0.5rem;
    min-block-size: 2.25rem;
    padding: 0 0.9375rem;
    border: 1px solid oklch(100% 0 0 / 0.11);
    border-radius: 999px;
    font-size: 0.84rem;
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
    color: var(--wall-ink-muted);
    background: var(--wall-chip-surface);
    box-shadow: inset 0 1px 0 oklch(100% 0 0 / 0.04);
    cursor: pointer;
    user-select: none;
    appearance: none;
    transition: color 0.2s, background-color 0.2s, border-color 0.2s;
    -webkit-tap-highlight-color: transparent;
  }

  @media (hover: hover) {
    .wall-chip:hover,
    .wall-pause:hover {
      --wall-chip-surface: var(--wall-face-head);

      border-color: oklch(100% 0 0 / 0.24);
      color: var(--wall-ink);
    }
  }

  .wall-chip:active,
  .wall-pause:active {
    --wall-chip-surface: oklch(23% 0.008 265);

    border-color: oklch(100% 0 0 / 0.3);
    color: var(--wall-ink);
    transition-duration: 0.05s;
  }

  /* The active chip is the one light object in the bar. */
  .wall-chip[aria-pressed="true"],
  .wall-pause[aria-pressed="true"] {
    --wall-chip-surface: oklch(95% 0 0);

    border-color: transparent;
    color: oklch(15% 0 0);
    box-shadow: 0 0.5rem 1.5rem -0.75rem oklch(100% 0 0 / 0.45);
  }

  @media (hover: hover) {
    .wall-chip[aria-pressed="true"]:hover,
    .wall-pause[aria-pressed="true"]:hover {
      --wall-chip-surface: oklch(100% 0 0);
    }
  }

  .wall-chip[aria-pressed="true"]:active,
  .wall-pause[aria-pressed="true"]:active {
    --wall-chip-surface: oklch(86% 0 0);
  }

  .wall-chip:focus-visible,
  .wall-pause:focus-visible {
    outline-offset: 2px;
  }

  /* One dot per cluster a lens gathers, in that cluster's hue: the chips are
   * the key to the colors on the wall. Two dots overlap, each ringed in the
   * chip's own surface so they stay two. */
  .wall-chip-hues {
    display: inline-flex;
  }

  .wall-chip-hue {
    inline-size: 0.5rem;
    block-size: 0.5rem;
    border-radius: 50%;
    background: var(--wall-accent);
    box-shadow: 0 0 0 1.5px var(--wall-chip-surface);
    transition: box-shadow 0.2s;
  }

  .wall-chip-hue + .wall-chip-hue {
    margin-inline-start: -0.125rem;
  }

  .wall-chip[aria-pressed="true"] .wall-chip-hue {
    background: oklch(60% var(--wall-chroma) var(--wall-hue));
  }

  /* The pause control's mark: two bars, drawn in its own ink. */
  .wall-pause::before {
    inline-size: 0.1875rem;
    block-size: 0.625rem;
    border-radius: 1px;
    background: currentColor;
    box-shadow: 0.3125rem 0 0 currentColor;
    margin-inline-end: 0.3125rem;
    content: "";
  }

  /* A little under the width where the row fits, the chips close up, so the
   * row still fits a common laptop instead of losing its last few pixels. */
  @media (max-width: 82.5rem) {
    .wall-lens {
      gap: 0.375rem;
    }

    .wall-chip {
      padding-inline: 0.8125rem;
    }
  }

  /* A finger gets a taller chip, and the full 44 pixels around it. */
  @media (max-width: 42rem), (pointer: coarse) {
    .wall-chip {
      min-block-size: 2.5rem;
      padding-inline: 1rem;
      font-size: 0.875rem;
    }

    .wall-chip::after {
      position: absolute;
      inset: -0.1875rem -0.25rem;
      content: "";
    }
  }

  /* A lens re-sorts the list: the cards it kept, this divider across every
   * column, then the rest. The list's order is all that places a card, and
   * no rule here moves or resizes one. Each card under the divider brings
   * its own gap above it, so the divider's margin there is that much less. */
  .wall-rest {
    column-span: all;
    margin-block: 1.75rem calc(1.25rem - var(--wall-gap));
    padding-block-start: 1rem;
    border-block-start: 1px solid oklch(100% 0 0 / 0.1);
    font-size: 0.8rem;
    font-weight: 500;
    letter-spacing: 0.02em;
    color: var(--wall-ink-faint);
  }

  /* A card under the divider is receded. It stays legible, because it can
   * still be read and opened: at this opacity its title and its line both
   * keep a contrast above 4.5 to 1 against the card. Taking its color away is
   * what makes it read as receded. */
  .wall-card {
    transition: opacity 0.3s ease, filter 0.3s ease;
  }

  .wall-card[data-receded] {
    opacity: 0.72;
    filter: saturate(0.08);
  }

  /* Pointing at a receded card, or reaching it by keyboard, brings that one
   * card back up. */
  @media (hover: hover) {
    .wall-card[data-receded]:hover {
      opacity: 1;
      filter: none;
    }
  }

  .wall-card[data-receded]:has(:focus-visible) {
    opacity: 1;
    filter: none;
  }

  @media (prefers-reduced-motion: reduce) {
    .wall-card {
      transition: none;
    }
  }

  /* The wall re-sorts under one cross-fade of the page. A card that recedes
   * or comes forward as it does takes its new look at once, inside that
   * fade, instead of fading a second time where it lands. */
  :root:active-view-transition .wall-card {
    transition: none;
  }

  /* The card that opened the sheet. While the two morph into each other the
   * card shares the sheet's transition name; while the sheet is open the card
   * has become the sheet, so its place on the wall stays empty. Neither state
   * moves the card or touches any other.
   *
   * In both states the card paints through a layer of its own: the shared
   * name makes one, and so does an opacity of nothing. WebKit leaves the
   * cards after such a card out of the page's picture unless the card's paint
   * stays inside its box, so a marked card contains its paint, in the face's
   * own rounded shape. Nothing is lost by it: a held card is unseen, and the
   * box that carries the morph clips its pictures to a shape of its own. */
  .wall-card[data-wall-opening] {
    border-radius: var(--wall-radius);
    transition: none;
    contain: paint;
  }

  .wall-card[data-wall-opening="morph"] {
    view-transition-name: wall-open;
  }

  .wall-card[data-wall-opening="held"] {
    opacity: 0;
  }

  /* The marked card holds still, its face and its glyph. The browser reports
   * the pointer gone from the card as its transition begins, and a face left
   * to ease out of its lifted, tilted pose would do it unseen. A face that
   * moves has a layer of its own, and the marked card is a stacking context,
   * so that layer cannot rise above the other cards: the browser lifts every
   * card after it into further layers and draws them all again, and once
   * more when the face comes to rest. So the face rests at once, its two
   * layers take their look at once, and the glyph takes its pose at once.
   *
   * These rules need the root out of the sheet's transition, which the rule
   * for the marked root sees to. With the root still pictured on every frame,
   * WebKit's frames come late once the face holds still. */
  .wall-card[data-wall-opening] .wall-card-face {
    z-index: 0;
    transform: none;
    transition: none;
    will-change: auto;
  }

  .wall-card[data-wall-opening] .wall-card-face::before,
  .wall-card[data-wall-opening] .wall-card-face::after,
  .wall-card[data-wall-opening] .wall-glyph-move {
    transition: none;
  }

  /* Where a pointer can hover, the visitor pressed a lit card, and the
   * browser lets go of the hover before it takes the card's picture. The card
   * keeps its lit face until the page changes, so the picture that grows into
   * the sheet shows the card as it was pressed. A card the sheet returns to
   * is marked once the page has changed, and arrives as the pointer and the
   * keyboard have left it. */
  @media (hover: hover) {
    :root:not([data-wall-sheet-moving]) .wall-card[data-wall-opening="morph"] .wall-card-face::before {
      opacity: 1;
    }
  }

  /* The card's mark, its glyph or its numeral, crosses to the sheet as an
   * object of its own. The card names it while the card carries the shared
   * name, and the sheet names it while a card is its source, so the name
   * never stands on two boxes at once. A sheet with no source card keeps its
   * mark in its own picture, and arrives and leaves whole.
   *
   * A receded card's mark stays in the card's picture. The browser lifts a
   * named box out of whatever dims its card, and the mark would arrive at a
   * dimmed card at full strength. */
  .wall-card[data-wall-opening="morph"]:not([data-receded]) :is(.wall-card-glyph, .wall-card-numeral),
  :root:has(.wall-card[data-wall-opening]:not([data-receded])) .wall-open :is(.wall-open-glyph, .wall-open-numeral) {
    view-transition-name: wall-open-mark;
  }

  /* The opened card: a sheet in a modal dialog. The page behind it holds its
   * place. Stopping its scroll removes its scrollbar, so the page is padded by
   * the width the dialog measured for it, and nothing shifts as the sheet
   * opens or closes. */
  :root:has(.wall-open[open]) {
    padding-inline-end: var(--wall-open-scrollbar);
    overflow: hidden;
  }

  .wall-open {
    /* The sheet's padding, and the close control's size and its distance
     * from the sheet's top corner. The control's place is worked out from
     * all three, so a screen that changes one moves nothing else. */
    --wall-open-pad: 2rem;
    --wall-open-close: 2.25rem;
    --wall-open-close-inset: 1rem;

    inline-size: min(34rem, calc(100vw - 2rem));
    max-block-size: calc(100dvh - 2rem);
    margin: auto;
    padding: 0;
    border: 0;
    overflow: visible;
    border-radius: 1.5rem;
    font: inherit;
    color: var(--wall-ink);
    background: none;

    /* The shadow belongs to the dialog, not the face, so it fades in where
     * the sheet will rest instead of travelling with the morph. The dialog
     * goes by a transition name of its own for it. While the dialog's face
     * is in a transition and the page's root is not, Chrome draws nothing of
     * the dialog's own box, and a shadow left to the page would arrive all
     * at once as the transition ended. */
    box-shadow: 0 2.5rem 5.5rem -1.75rem oklch(0% 0 0 / 0.9);
    view-transition-name: wall-open-shadow;
  }

  .wall-open::backdrop {
    background: oklch(7% 0.01 265 / 0.74);
  }

  /* The sheet is the card, grown: the same opaque near-black face, the same
   * hairline that catches the cluster's hue at the top-left corner, and the
   * same corner wash, all a size up. */
  .wall-open-face {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    justify-items: start;
    max-block-size: inherit;
    padding: var(--wall-open-pad) var(--wall-open-pad)
      calc(var(--wall-open-pad) + 0.125rem);
    border: 1px solid transparent;
    border-radius: 1.5rem;
    overflow: auto;
    background:
      radial-gradient(
      26rem circle at 0 0,
      oklch(60% calc(var(--wall-chroma) * 1.25) var(--wall-hue) / 0.2),
      transparent 72%
    )
      padding-box,
      linear-gradient(180deg, var(--wall-sheet-head), var(--wall-face-foot))
      padding-box,
      radial-gradient(
      22rem circle at 0 0,
      oklch(86% var(--wall-chroma) var(--wall-hue) / 0.6),
      transparent 72%
    )
      border-box,
      linear-gradient(180deg, oklch(100% 0 0 / 0.18), oklch(100% 0 0 / 0.07))
      border-box;
    box-shadow: inset 0 1px 0 oklch(100% 0 0 / 0.06);
    view-transition-name: wall-open;
  }

  .wall-open :is(a, button):focus-visible {
    outline-color: var(--wall-accent);
  }

  /* The close control sits in the sheet's top corner and comes first, so it
   * holds focus as the sheet opens. It is the first row of the face and
   * takes no room there: its margins lift it into the corner and give back
   * its own height, so the sheet is laid out as if the control were not in
   * it. A sheet too tall for its screen scrolls inside its face, and the
   * control stays in the corner while the words pass under it, in reach of a
   * pointer however far the sheet has scrolled. A browser measures where a
   * box sticks from inside the scrolling box's padding, so the distance it
   * sticks at is the same lift its margin gives it.
   *
   * The control is opaque. It is laid on the color of the sheet's head and
   * not on the sheet behind it, because the sheet's words scroll under it. */
  .wall-open-close {
    --wall-open-close-lift: calc(
      var(--wall-open-close-inset) - var(--wall-open-pad)
    );

    position: sticky;
    z-index: 1;
    inset-block-start: var(--wall-open-close-lift);
    display: grid;
    place-items: center;
    justify-self: end;
    inline-size: var(--wall-open-close);
    block-size: var(--wall-open-close);
    margin-block: var(--wall-open-close-lift)
      calc(0px - var(--wall-open-close-lift) - var(--wall-open-close));
    margin-inline-end: var(--wall-open-close-lift);
    padding: 0;
    border: 1px solid oklch(100% 0 0 / 0.1);
    border-radius: 50%;
    color: var(--wall-ink-muted);
    background: color-mix(
      in oklch,
      oklch(100% 0 0) 4%,
      var(--wall-sheet-head)
    );
    cursor: pointer;
    appearance: none;
    transition: color 0.2s, background-color 0.2s, border-color 0.2s;
    -webkit-tap-highlight-color: transparent;
  }

  @media (hover: hover) {
    .wall-open-close:hover {
      border-color: oklch(100% 0 0 / 0.24);
      color: var(--wall-ink);
      background: color-mix(
        in oklch,
        oklch(100% 0 0) 8%,
        var(--wall-sheet-head)
      );
    }
  }

  .wall-open-close:active {
    border-color: oklch(100% 0 0 / 0.3);
    color: var(--wall-ink);
    background: color-mix(
      in oklch,
      oklch(100% 0 0) 13%,
      var(--wall-sheet-head)
    );
  }

  .wall-open-cross {
    fill: none;
    stroke: currentColor;
    stroke-width: 1.5;
    stroke-linecap: round;
  }

  .wall-open-glyph {
    inline-size: 4.75rem;
    block-size: 4.75rem;
    margin-block-end: 1.5rem;
    color: var(--wall-accent);
  }

  /* A word longer than a narrow sheet is wide breaks where it must, as it
   * does on the card. */
  .wall-open-title {
    font-size: 1.75rem;
    font-weight: 600;
    line-height: 1.14;
    letter-spacing: -0.028em;
    text-wrap: balance;
    overflow-wrap: anywhere;
  }

  /* A numeral leads its heading, as it does on the card, and is set as the
   * card sets it, a size up: the two are one drawing as the card opens. */
  .wall-open-numeral {
    display: block;
    margin-block-end: 1.25rem;
    font-family: var(--discern-font-marketing);
    font-size: 6rem;
    line-height: 0.86;
    letter-spacing: -0.055em;
    color: var(--wall-accent);
  }

  /* A statement is its own headline, under the short rule its card carries.
   * The rule starts clear of the close control. */
  .wall-open--statement .wall-open-title {
    padding-block-start: 0.5rem;
    font-family: var(--discern-font-marketing);
    font-size: 2.125rem;
    line-height: 1.1;
    letter-spacing: -0.034em;
  }

  .wall-open--statement .wall-open-title::before {
    display: block;
    inline-size: 2.5rem;
    block-size: 3px;
    margin-block-end: 1.75rem;
    border-radius: 2px;
    background: var(--wall-accent);
    content: "";
  }

  .wall-open-line {
    margin-block-start: 0.75rem;
    font-size: 1.0625rem;
    line-height: 1.5;
    text-wrap: pretty;
  }

  .wall-open-more {
    margin-block-start: 0.875rem;
    font-size: 0.96875rem;
    line-height: 1.55;
    color: var(--wall-ink-muted);
    text-wrap: pretty;
  }

  .wall-open--statement .wall-open-more {
    margin-block-start: 1.125rem;
    font-size: 1.0625rem;
  }

  .wall-open-foot {
    margin-block-start: 1.75rem;
  }

  /* The way on into the manual, in the cluster's hue. It is named by the
   * page it leads to, and a name too long for a narrow sheet takes a second
   * line inside it. */
  .wall-open-link {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    max-inline-size: 100%;
    min-block-size: 2.5rem;
    padding: 0.4375rem 1rem;
    border: 1px solid oklch(86% var(--wall-chroma) var(--wall-hue) / 0.32);
    border-radius: 0.75rem;
    font-size: 0.9375rem;
    font-weight: 550;
    line-height: 1.3;
    letter-spacing: -0.005em;
    overflow-wrap: anywhere;
    text-decoration: none;
    color: var(--wall-accent);
    background: oklch(60% var(--wall-chroma) var(--wall-hue) / 0.1);
    transition: background-color 0.2s, border-color 0.2s;
  }

  @media (hover: hover) {
    .wall-open-link:hover {
      border-color: oklch(86% var(--wall-chroma) var(--wall-hue) / 0.6);
      background: oklch(60% var(--wall-chroma) var(--wall-hue) / 0.18);
    }
  }

  .wall-open-link:active {
    background: oklch(60% var(--wall-chroma) var(--wall-hue) / 0.26);
  }

  @media (max-width: 42rem) {
    .wall-open {
      --wall-open-pad: 1.5rem;
      --wall-open-close-inset: 0.75rem;
    }

    .wall-open,
    .wall-open-face {
      border-radius: 1.25rem;
    }

    .wall-open-glyph {
      inline-size: 4rem;
      block-size: 4rem;
      margin-block-end: 1.25rem;
    }

    .wall-open-title {
      font-size: 1.5rem;
    }

    .wall-open-numeral {
      font-size: 5rem;
    }

    .wall-open--statement .wall-open-title {
      font-size: 1.75rem;
    }
  }

  /* A finger gets the full 44 pixels on both of the sheet's controls: on a
   * narrow screen, and on a wide one that is touched. */
  @media (max-width: 42rem), (pointer: coarse) {
    .wall-open {
      --wall-open-close: 2.75rem;
    }

    .wall-open-link {
      min-block-size: 2.75rem;
    }
  }

  /* Opening and closing. The card and the sheet share one transition name, so
   * the browser grows the one into the other; everything else on the page
   * cross-fades in place and nothing but that one object moves.
   *
   * While a transition runs the browser answers every press at the page's
   * root, or at the dialog of a sheet that is arriving, whatever lies under
   * it. Script reads such a press by where it fell: a click outside the
   * arriving sheet still closes it, and a click on the page while the sheet
   * leaves still reaches what it was aimed at. */

  /* A sheet's transition takes the page's old picture and never a new one.
   * Script marks the root as the page changes, and the root has no transition
   * name from then until the transition ends. The old picture fades out over
   * the page itself, which is the same cross-fade to the eye, and the page
   * under it is drawn as it always is. A browser that draws a new picture of
   * the page afresh on every frame of a transition then has none to draw. A
   * lens leaves the root its name, and cross-fades the page's two pictures. */
  :root[data-wall-sheet-moving] {
    view-transition-name: none;
  }

  /* The sheet's shadow fades in and out where the sheet rests, on the
   * clock of the page's own pictures. */
  ::view-transition-old(root),
  ::view-transition-new(root),
  ::view-transition-old(wall-open-shadow),
  ::view-transition-new(wall-open-shadow) {
    animation-duration: 0.3s;
  }

  /* The object gathers speed before it travels and settles slowly, so it
   * never lunges: a tenth of the way in the first three frames, half by a
   * quarter of the time.
   *
   * It is raised above the sheet's shadow. A browser stacks a picture that
   * only the new state has above every other, which would lay an arriving
   * sheet's shadow over the sheet. */
  ::view-transition-group(wall-open),
  ::view-transition-group(wall-open-mark) {
    z-index: 1;
    animation-duration: 0.42s;
    animation-timing-function: cubic-bezier(0.3, 0.1, 0.1, 1);
  }

  /* The way back is a little quicker than the way out. The card carries the
   * shared name only while the sheet returns to it. */
  :root:has(.wall-card[data-wall-opening="morph"])::view-transition-group(wall-open),
  :root:has(.wall-card[data-wall-opening="morph"])::view-transition-group(wall-open-mark) {
    animation-duration: 0.34s;
  }

  /* The mark travels on the box, in step with it, as one drawing that grows:
   * its two pictures are the same mark at two sizes, each scaled to the
   * travelling box's height and hung from its top-left corner, so they lie
   * on each other as one fades into the other. A numeral's box is as wide as
   * its heading, which differs between the card and the sheet, so the height
   * alone sets the scale. */
  ::view-transition-old(wall-open-mark),
  ::view-transition-new(wall-open-mark) {
    inline-size: auto;
    block-size: 100%;
  }

  /* The morph, which runs only while a card is marked as the sheet's source.
   * The moving box is one solid object with one outline: it carries a face's
   * surface, halfway between the card's and the sheet's, and a face's
   * hairline, and it clips its two pictures to its shape. Both
   * pictures hang from the box's top-left corner and neither is squashed: the
   * outgoing one keeps the box's width, and the incoming one fills the box.
   * The two pictures say different words at different sizes, so they never
   * show together: the outgoing one is gone before the incoming one starts.
   * Between them the box shows its own plain surface, and on it the card's
   * mark, where the card has one that crosses. */
  :root:has(.wall-card[data-wall-opening])::view-transition-image-pair(wall-open) {
    border-radius: 1rem;
    outline: 1px solid oklch(100% 0 0 / 0.13);
    outline-offset: -1px;
    overflow: clip;
    background: linear-gradient(
      180deg,
      color-mix(in oklch, var(--wall-face-head), var(--wall-sheet-head)),
      var(--wall-face-foot)
    );
  }

  :root:has(.wall-card[data-wall-opening])::view-transition-old(wall-open),
  :root:has(.wall-card[data-wall-opening])::view-transition-new(wall-open) {
    mix-blend-mode: normal;
  }

  :root:has(.wall-card[data-wall-opening])::view-transition-new(wall-open) {
    block-size: 100%;
    object-fit: cover;
    object-position: 0 0;
  }

  /* On the way out the card's picture is the shorter of the two, so its foot
   * would show as a line inside the growing box. It is feathered away; the
   * box's own outline stands in for the card's from the first frame. */
  :root:has(.wall-card[data-wall-opening="held"])::view-transition-old(wall-open) {
    mask-image: linear-gradient(
      180deg,
      oklch(0% 0 0) calc(100% - 1.5rem),
      transparent
    );
  }

  @keyframes wall-open-out {
    to {
      opacity: 0;
    }
  }

  @keyframes wall-open-in {
    from {
      opacity: 0;
    }
  }

  :root:has(.wall-card[data-wall-opening])::view-transition-old(wall-open) {
    animation: wall-open-out 0.06s linear both;
  }

  :root:has(.wall-card[data-wall-opening])::view-transition-new(wall-open) {
    animation: wall-open-in 0.12s 0.06s linear both;
  }

  /* On the way back the incoming picture is the card's, which is shorter
   * for its width than the box it arrives in. Filling that box would draw
   * its words several times their size and cut every line at the box's
   * edge. So it keeps the box's width and its own shape, as the outgoing
   * picture does, and its words are whole from the first frame they show. */
  :root:has(.wall-card[data-wall-opening="morph"])::view-transition-new(wall-open) {
    block-size: auto;
  }

  /* With no card to grow from or return to, as in the far view where the
   * wall is tilted, the sheet arrives and leaves where it stands. */
  @keyframes wall-open-arrive {
    from {
      opacity: 0;
      transform: scale(0.97);
    }
  }

  @keyframes wall-open-leave {
    to {
      opacity: 0;
      transform: scale(0.985);
    }
  }

  ::view-transition-new(wall-open):only-child {
    animation: wall-open-arrive 0.26s cubic-bezier(0.2, 0.8, 0.2, 1) both;
  }

  ::view-transition-old(wall-open):only-child {
    animation: wall-open-leave 0.16s ease-in both;
  }

  /* A browser with no view transitions gets a short fade as the sheet opens,
   * where motion is welcome. Reduced motion gets no animation at all: the
   * hook starts no transition, and none could run if one were started. */
  @keyframes wall-open-fade {
    from {
      opacity: 0;
    }
  }

  @supports not (view-transition-name: none) {
    @media (prefers-reduced-motion: no-preference) {
      .wall-open[open] > .wall-open-face,
      .wall-open[open]::backdrop {
        animation: wall-open-fade 0.16s ease-out;
      }
    }
  }

  @media (prefers-reduced-motion: reduce) {
    ::view-transition-group(*),
    ::view-transition-old(*),
    ::view-transition-new(*) {
      animation: none;
    }
  }

  /* Forced colors and print: the system's own colors, and states that do not
   * depend on a background the system has replaced. */
  @media (forced-colors: active) {
    .wall-chip[aria-pressed="true"],
    .wall-pause[aria-pressed="true"] {
      border-color: Highlight;
      color: HighlightText;
      background: Highlight;
      forced-color-adjust: none;
    }

    .wall-chip-hues {
      display: none;
    }

    .wall-open {
      --wall-accent: CanvasText;
      box-shadow: none;
    }

    .wall-open-face {
      border-color: CanvasText;
      background: Canvas;
      box-shadow: none;
    }
  }

  /* A reader who asks for more contrast gets firmer edges on the controls
   * and the divider, and receded cards nearer to full strength. The divider
   * still says which cards the lens set aside. */
  @media (prefers-contrast: more) {
    .wall-chip,
    .wall-pause,
    .wall-open-close,
    .wall-rest {
      border-color: oklch(100% 0 0 / 0.5);
    }

    .wall-card[data-receded] {
      opacity: 0.86;
    }
  }

  @media print {
    .wall-card[data-receded] {
      opacity: 1;
      filter: none;
    }

    /* On paper the gap lies under each card, so the divider keeps the
     * whole of its own margin. */
    .wall-rest {
      margin-block-end: 1.25rem;
      border-color: CanvasText;
    }

    /* Paper gets the wall. A sheet that was open stays off the page, the
     * card it grew from shows in its own place again, and the page behind
     * prints at its full width and length. */
    .wall-open,
    .wall-open::backdrop {
      display: none;
    }

    .wall-card[data-wall-opening] {
      opacity: 1;
    }

    :root:has(.wall-open[open]) {
      padding-inline-end: 0;
      overflow: visible;
    }
  }
}
