:root {
    color-scheme: dark;
    font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    /* The notch and the home indicator, for my-clock.js to keep the
       setting lists clear of. */
    --safe-top: env(safe-area-inset-top, 0px);
    --safe-right: env(safe-area-inset-right, 0px);
    --safe-bottom: env(safe-area-inset-bottom, 0px);
    --safe-left: env(safe-area-inset-left, 0px);
    /* An open menu's button, the cross that closes it: smaller than the
       rest, its cross the same size (my-clock.js places rows from it). */
    --close-size: 30px;
    --toggle-resize: width 200ms ease, height 200ms ease, min-height 200ms ease;
    /* The light, from up to the left of whoever holds the phone: in the
       iPhone app, which stays in portrait, turned with them (my-clock.js,
       `goClockTurn`), and swung round as it turns so that the shadows go
       round with the icons. A shadow's offset is as it falls held upright,
       (x, y), turned by this: the helpers below are the ones the menus
       share, the board and the stones working theirs out in place. */
    --turn-cos: cos(var(--turn));
    --turn-sin: sin(var(--turn));
    --lit-edge: calc(-1px*var(--turn-sin)) calc(1px*var(--turn-cos));
    --fall-0-2: calc(-2px*var(--turn-sin)) calc(2px*var(--turn-cos));
    --fall-0-3: calc(-3px*var(--turn-sin)) calc(3px*var(--turn-cos));
    --fall-1-2: calc(1px*var(--turn-cos) - 2px*var(--turn-sin)) calc(1px*var(--turn-sin) + 2px*var(--turn-cos));
    --fall-2-4: calc(2px*var(--turn-cos) - 4px*var(--turn-sin)) calc(2px*var(--turn-sin) + 4px*var(--turn-cos));
    --fall-5-10: calc(5px*var(--turn-cos) - 10px*var(--turn-sin)) calc(5px*var(--turn-sin) + 10px*var(--turn-cos));
    transition: --turn 350ms ease-in-out;
}

@property --turn {
    syntax: '<angle>';
    inherits: true;
    initial-value: 0deg;
}

* {
    box-sizing: border-box;
}

html,
body {
    width: 100%;
    height: 100%;
    margin: 0;
    overflow: hidden;
    /* The page is the whole screen in the iOS app; nothing should rubber-band. */
    overscroll-behavior: none;
}

body {
    background: #2f3432;
    color: #261917;
    /* A long press on the board is not a request to select or share a stone. */
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
}

#about_box,
#about_box * {
    -webkit-user-select: text;
    user-select: text;
}

[hidden] {
    display: none !important;
}

#sb-site {
    position: relative;
    z-index: 1;
    width: 100%;
    min-height: 100vh;
    background-size: cover;
    background-position: center;
}

/* The water's two layers, drifting across each other (my-clock.js
   showDrift): under everything, the background as it was fading out
   over them too; the upper one softly lighting the lower, and neither
   anything else under them. */
.table-drift {
    position: absolute;
    inset: 0;
    z-index: -1;
    overflow: hidden;
    isolation: isolate;
    pointer-events: none;
}

.table-drift > div {
    position: absolute;
    background-repeat: repeat;
    will-change: transform;
}

.table-drift > div:nth-child(2) {
    opacity: 0.45;
}

/* The water alive (live-water.js): under everything, filling the screen,
   in place of the water's two layers. */
.live-water {
    position: fixed;
    inset: 0;
    z-index: -1;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

/* The background as it was, fading out over the new one (my-clock.js
   fadeFromBackground): over the page's own, under everything else. */
.background-fade {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
}

#goban {
    position: relative;
    min-height: 100vh;
    min-height: 100dvh;
    padding-top: 1px;
    padding-bottom: 1px;
    overflow: hidden;
    /* A one- or two-finger drag is the hand for my-clock.js to read, not a
       pan; pinch zoom is left to the browser (Safari allows it, the iOS app
       does not, so there a two-finger drag is never mistaken for one). */
    touch-action: pinch-zoom;
}

/* The board's shadow on the table, lit as the stones are, from up to the
   left (shadowFall, stone-dom.js), and measured, as they are, in stone
   widths (`--stone`, go-clock.js): a tight dark line where the board
   meets the table, the shadow it casts falling away down and to the
   right, and the table a little darker all round it. On water, fainter,
   the light broken up by the surface; in space, nothing for a shadow to
   fall on. */
#goban-image {
    box-shadow:
        calc(var(--stone)*(0.12*var(--turn-cos) - 0.14*var(--turn-sin))) calc(var(--stone)*(0.12*var(--turn-sin) + 0.14*var(--turn-cos))) calc(var(--stone)*0.2) rgb(0 0 0 / 0.5),
        calc(var(--stone)*(0.55*var(--turn-cos) - 0.65*var(--turn-sin))) calc(var(--stone)*(0.55*var(--turn-sin) + 0.65*var(--turn-cos))) calc(var(--stone)*1.2) rgb(0 0 0 / 0.5),
        0 0 calc(var(--stone)*0.8) rgb(0 0 0 / 0.25);
}

/* Floating, the board lies in the water rather than above it: a thin
   light line where the water meets its edge, the water dark and wet
   right against it, and its shadow in the water close under it. */
[data-surface="water"] #goban-image {
    box-shadow:
        0 0 0 calc(var(--stone)*0.06) rgb(210 232 238 / 0.4),
        0 0 calc(var(--stone)*0.35) calc(var(--stone)*0.08) rgb(0 14 22 / 0.55),
        calc(var(--stone)*(0.2*var(--turn-cos) - 0.24*var(--turn-sin))) calc(var(--stone)*(0.2*var(--turn-sin) + 0.24*var(--turn-cos))) calc(var(--stone)*1.4) rgb(0 12 20 / 0.4);
}

[data-surface="void"] #goban-image,
[data-water="live"] #goban-image {
    box-shadow: none;
}

#goban img {
    display: block;
    max-width: 100%;
    max-height: 100%;
    margin-right: auto;
    margin-left: auto;
    /* Dragging the board is a swipe, not a picture being picked up. */
    -webkit-user-drag: none;
}

.board_pos {
    pointer-events: none;
    z-index: 2;
}

.stone-shadow {
    position: absolute;
    z-index: 0;
    inset: 0;
    opacity: var(--stone-shadow-opacity, 0.62);
    pointer-events: none;
    transform: translate(
        calc(var(--stone-shadow-offset-x, 1.25px)*var(--turn-cos) - var(--stone-shadow-offset-y, 1.75px)*var(--turn-sin)),
        calc(var(--stone-shadow-offset-x, 1.25px)*var(--turn-sin) + var(--stone-shadow-offset-y, 1.75px)*var(--turn-cos)));
    transform-origin: center;
}

/* A shadow, and a stone out of focus, are pictures drawn ahead of time at
   a few heights (soft.js): the one below the stone's height, and the one
   above it faded in over it. Which pictures, how far out beyond the stone
   they reach (`inset`) and the pictures themselves are rules stone-dom.js
   adds as it draws them. */
.stone-shadow::before,
.stone-shadow::after,
.stone-focus::before,
.stone-focus::after {
    content: '';
    position: absolute;
    background: no-repeat center / 100% 100%;
}

.stone-shadow::after {
    opacity: var(--stone-shadow-mix, 0);
}

.stone-focus {
    position: absolute;
    z-index: 1;
    pointer-events: none;
}

.stone-focus::before,
.stone-focus::after {
    inset: 0;
}

.stone-focus::after {
    opacity: var(--stone-focus-mix, 0);
}

.stone-focus[hidden],
.stone[hidden] ~ .stone-focus,
.flying > .stone-focus {
    display: none;
}

/* The hand pushing the stones about (one disc per finger down), the arm
   sweeping the board (sweep.js), and the stones while they are loose under
   them or lying on the table. */
#finger,
#finger2,
#arm {
    position: absolute;
    z-index: 5;
    border: 1px solid rgb(255 255 255 / 0.45);
    border-radius: 50%;
    background: rgb(255 255 255 / 0.16);
    box-shadow: inset 0 0 12px rgb(255 255 255 / 0.25), 0 2px 8px rgb(0 0 0 / 0.25);
    pointer-events: none;
}

#arm {
    z-index: 100;
    overflow: visible;
    border: 0;
    background: none;
    box-shadow: none;
    filter: drop-shadow(0 2px 8px rgb(0 0 0 / 0.25));
}

#arm path {
    fill: rgb(255 255 255 / 0.16);
    stroke: rgb(255 255 255 / 0.45);
    stroke-width: 1;
}

/* None are drawn for now: the stones moving are enough to show the hand
   and the arm. Delete this rule to bring the discs back. */
#finger,
#finger2,
#arm {
    visibility: hidden;
}

.loose-stone {
    z-index: 3;
}

/* A finger held still until it goes off (hand.js): a flash under the
   finger, and the shockwave, with a fainter echo behind it, flung out
   over the stones. Hot and bright, with a dark edge, so it shows on a
   pale board as well as a dark one. */
.blast-flash,
.blast-ring {
    position: absolute;
    z-index: 6;
    border-radius: 50%;
    pointer-events: none;
}

.blast-flash {
    background: radial-gradient(circle, rgb(255 255 240 / 1), rgb(255 200 90 / 0.9) 25%, rgb(255 120 20 / 0.5) 50%, rgb(255 90 0 / 0) 72%);
}

.blast-ring {
    border: 12px solid rgb(255 245 200);
    background: radial-gradient(circle, rgb(255 120 0 / 0) 40%, rgb(255 120 0 / 0.45) 85%, rgb(255 160 40 / 0.75));
    box-shadow:
        0 0 0 3px rgb(255 100 0),
        0 0 0 7px rgb(70 20 0 / 0.45),
        0 0 40px 16px rgb(255 110 0 / 0.7),
        inset 0 0 0 3px rgb(255 100 0),
        inset 0 0 36px 10px rgb(255 130 20 / 0.75);
}

.blast-ring.echo {
    border-width: 5px;
    background: none;
    box-shadow:
        0 0 0 2px rgb(255 100 0),
        0 0 0 5px rgb(70 20 0 / 0.35),
        0 0 24px 8px rgb(255 110 0 / 0.55);
}

/* A stone the magic has in the air (magic.js) passes over the rest, and
   over the menus too, which stand on the table (the toolbar and the
   board's menu at 20, the tools' rows at 15), though under the game's
   kifu held up over everything (201). */
.magic-stone {
    z-index: 22;
}

/* A stone ridden up onto another (physics.js) lies over it. */
.loose-stone.riding {
    z-index: 4;
}

/* A stone let go in mid-air (hand.js) is over everything it falls on. */
.loose-stone.in-air {
    z-index: 22;
}

/* A stone tumbling in space wears a frame of its tumble sheet (flight.js);
   one risen off the board passes over everything else, the menus and the
   magic's stones too. */
.flying {
    background-repeat: no-repeat;
}

.rising {
    z-index: 23;
}

/* A stone flying off into space, moved by its transform alone
   (flightTranslate, flight.js), a layer of its own: moving it is then
   only moving the layer, nothing under it drawn again. */
.rising.flying {
    will-change: transform;
}

/* A ring of ripple where a stone went into the water (water.js), under
   the stones, and a drop of water flung up by the splash, over them. */
.ripple {
    position: absolute;
    z-index: 2;
    border: 1.5px solid rgb(255 255 255 / 0.75);
    border-radius: 50%;
    box-shadow: 0 0 6px rgb(255 255 255 / 0.35), inset 0 0 6px rgb(255 255 255 / 0.35);
    pointer-events: none;
}

.droplet {
    position: absolute;
    z-index: 6;
    border-radius: 50%;
    background: rgb(255 255 255 / 0.85);
    box-shadow: 0 0 4px rgb(255 255 255 / 0.6);
    pointer-events: none;
}

.stone {
    position: relative;
    z-index: 1;
    display: block;
    width: 100%;
    height: 100%;
    background: transparent;
}

/* The photographs of the stones were lit from up to the left too, so
   they turn with the light (the flat stones and the tumbling sheets,
   lit from the front, do not need to). */
.stone,
.stone-focus {
    rotate: var(--turn);
}

/* The controls: a row along the top of the screen in portrait, from the
   left. Tucked away, nothing but the toggle at the left is left; the
   rest slide out from under it and back. */
.toolbar {
    position: fixed;
    top: max(10px, env(safe-area-inset-top));
    left: max(10px, env(safe-area-inset-left));
    z-index: 20;
    display: flex;
    align-items: center;
    gap: 6px;
    width: max-content;
    max-width: calc(100vw - 20px - env(safe-area-inset-left) - env(safe-area-inset-right));
    /* The toolbar's own box is see-through to touches: only its controls
       take them, so a tap between buttons reaches the board. */
    pointer-events: none;
}

.toolbar > * {
    pointer-events: auto;
}

/* The setting buttons, and the tools button: a row, wrapping if it must. */
.toolbar-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 6px;
    min-width: 0;
}

/* The board's own menu, at the bottom right: its button, and the board's
   settings coming out from under it leftwards along the row, as the
   toolbar's own do rightwards, each opening its choices above
   (my-clock.js places them). Apart from the toolbar's, it can be open
   with it; it stays when that is tucked away, dimming and waking with its
   toggle (below), and full strength while open. */
.board-control {
    position: fixed;
    bottom: max(10px, env(safe-area-inset-bottom));
    right: max(10px, env(safe-area-inset-right));
    flex-direction: row-reverse;
    z-index: 20;
    display: flex;
    align-items: center;
    gap: 6px;
}

.board-actions {
    display: flex;
    flex-direction: row-reverse;
    align-items: center;
    gap: 6px;
}

/* As the toolbar's own box is (above), the board menu's is see-through to
   touches: closed, it still spans the width of its hidden settings, which
   would otherwise keep a tap from whatever lies under them. Only its
   button and its settings (while they show) take them. */
.board-control,
.board-actions {
    pointer-events: none;
}

#board-toggle,
.board-actions > * {
    pointer-events: auto;
}

.board-actions > * {
    position: relative;
    top: 0;
    left: 0;
    transition: left 280ms ease-in-out, top 280ms ease-in-out, opacity 200ms ease, visibility 0s;
}

.board-control[data-open="false"] .board-actions > * {
    visibility: hidden;
    opacity: 0;
    /* Back under the button: each its own distance to the right, the
       first one step on from it. */
    left: calc(var(--i) * 48px + var(--close-size) + 6px);
    transition: left 280ms ease-in-out, top 280ms ease-in-out, opacity 200ms ease 80ms, visibility 0s 280ms;
}

/* In landscape the board's menu runs up the right-hand side instead,
   its settings coming out upwards from under its button (and their
   choices opening out to the left, beside them: my-clock.js). */
@media (orientation: landscape) {
    .board-control,
    .board-actions {
        flex-direction: column-reverse;
    }

    .board-control[data-open="false"] .board-actions > * {
        top: calc(var(--i) * 48px + var(--close-size) + 6px);
        left: 0;
    }
}

/* Out from under the toggle, showing as they go; and back the same way
   in reverse, fading as they arrive. Slid by a relative offset rather than
   a transform: a transform would make each button the frame its fixed
   list of choices is placed in (the faces), which would ride along with
   the slide and then jump. */
.toolbar-actions > * {
    position: relative;
    top: 0;
    left: 0;
    transition: left 280ms ease-in-out, top 280ms ease-in-out, opacity 200ms ease, visibility 0s;
}

.toolbar[data-collapsed="true"] .toolbar-actions > * {
    visibility: hidden;
    opacity: 0;
    /* Back under the toggle: each button its own distance to the left,
       the first one step on from it. */
    left: calc(var(--i) * -48px - var(--close-size) - 6px);
    transition: left 280ms ease-in-out, top 280ms ease-in-out, opacity 200ms ease 80ms, visibility 0s 280ms;
}

.button {
    display: grid;
    min-width: 0;
    padding: 0;
    border: 0;
    border-radius: 6px;
    place-items: center;
    background: rgb(0 0 0 / 0.62);
    color: white;
    cursor: pointer;
    font-family: Arial, sans-serif;
    line-height: 1;
    opacity: 1;
    box-shadow: var(--slab);
}

.menu-toggle {
    width: 42px;
    height: 42px;
    min-height: 42px;
    padding: 0;
    background: rgb(0 0 0 / 0.7);
    opacity: 0.85;
    transition: var(--toggle-resize);
}

/* Each menu's button leads its row, over the rest while they are tucked
   away; open, it wears a cross (my-clock.js), shrinking to fit it, and
   stays, the row sliding out beyond it, and a tap on it puts the row
   back. */
.toolbar .menu-toggle,
#board-toggle {
    position: relative;
    z-index: 1;
    flex: none;
}

.toolbar[data-collapsed="false"] .menu-toggle,
.board-control[data-open="true"] #board-toggle {
    width: var(--close-size);
    height: var(--close-size);
    min-height: var(--close-size);
}

.menu-toggle svg {
    display: block;
    width: 18px;
    height: 18px;
}

/* Every icon turned upright to whoever holds the phone, the button
   round it staying put (`--turn`, above). */
.menu-toggle svg,
.setting-icon svg {
    rotate: var(--turn);
}

/* Tucked away, the toggle dims well down after a while, so it is not
   the first thing seen, and the board's own menu with it; a touch
   anywhere (my-clock.js sets `awake` for a while) or a keyboard's focus
   brings them straight back, and neither dims while the other's menu is
   open. Awake or dimmed, the toggle wears the tool in use, white on
   dark, as the tool does in the open row. */
.toolbar[data-collapsed="true"] .menu-toggle {
    opacity: 0.45;
    transition: opacity 600ms ease, var(--toggle-resize);
}

.toolbar[data-collapsed="true"] .menu-toggle svg {
    width: 22px;
    height: 22px;
}

.toolbar[data-collapsed="true"] ~ .board-control {
    opacity: 0.45;
    transition: opacity 600ms ease;
}

.toolbar[data-collapsed="true"][data-awake="true"] .menu-toggle,
.toolbar[data-collapsed="true"][data-board-open="true"] .menu-toggle,
.toolbar[data-collapsed="true"] .menu-toggle:focus-visible {
    opacity: 1;
    transition: opacity 150ms ease, var(--toggle-resize);
}

.toolbar[data-collapsed="true"][data-awake="true"] ~ .board-control,
.toolbar[data-collapsed="true"] ~ .board-control[data-open="true"],
.toolbar[data-collapsed="true"] ~ .board-control:focus-within {
    opacity: 1;
    transition: opacity 150ms ease;
}

/* A setting is a button wearing its icon; open, its choices drop down
   beneath it (or, in landscape, open out to its right), the current one
   marked; a submenu is a choice in that list with a list of its own beside
   it. Where a list goes is my-clock.js's placePanel(), which keeps it on
   the screen. */
.setting-control {
    position: relative;
    color: white;
    font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    font-size: 13px;
    font-weight: 700;
    line-height: 1.1;
}

.setting-summary {
    display: grid;
    align-items: center;
    justify-items: center;
    width: 42px;
    min-height: 42px;
    padding: 0;
    border: 0;
    border-radius: 6px;
    background: rgb(0 0 0 / 0.7);
    color: inherit;
    cursor: pointer;
    font: inherit;
    text-align: left;
    white-space: nowrap;
    box-shadow: var(--slab);
}

/* A button in the row that is not a setting's own (the replay's) takes
   the white its neighbours get from .setting-control. */
.toolbar-actions > .setting-summary {
    color: white;
}

.setting-summary:focus-visible {
    background: rgb(0 0 0 / 0.8);
    outline: 2px solid rgb(255 255 255 / 0.8);
    outline-offset: -2px;
}

/* A button that is a toggle (the replay's information): pressed while
   what it started is showing. */
.replay-bar > .setting-summary[aria-pressed="true"] {
    background: rgb(255 255 255 / 0.85);
    color: #261917;
    box-shadow: inset var(--lit-edge) 0 rgb(255 255 255 / 0.9), var(--fall-1-2) 0 rgb(120 110 104 / 0.95), var(--fall-1-2) 3px rgb(0 0 0 / 0.3);
}

.setting-icon {
    width: 22px;
}

/* The icons (icons.js). */
.setting-icon svg {
    display: block;
    width: 22px;
    height: 22px;
}

/* A choice with an icon before its name, or after it (a toggle whose
   icon is what it shows: the sound). */
.choice-with-icon {
    grid-template-columns: 22px max-content;
    gap: 8px;
    padding-left: 6px;
}

.choice-with-trailing-icon {
    grid-template-columns: max-content 22px;
    gap: 10px;
    padding-right: 6px;
}

.setting-options {
    position: fixed;
    top: 0;
    left: 0;
    /* Under its button, so the choices come out from under it. (Not the
       button raised over it instead: that would put the button's rim
       over its face.) */
    z-index: -1;
    display: grid;
    /* One column as wide as the widest choice, which the rest fill. */
    grid-template-columns: max-content;
    gap: 4px;
    padding: 6px;
    border-radius: 6px;
    background: rgb(0 0 0 / 0.75);
    box-shadow: var(--fall-0-3) 14px rgb(0 0 0 / 0.32);
    transition: opacity 200ms ease, visibility 0s;
}

/* Closed, a list fades with its own choices (below); open, both are
   immediate, the choices sliding out to show themselves. */
.setting-control[data-open="false"] > .setting-options {
    opacity: 0;
    visibility: hidden;
    transition: opacity 200ms ease, visibility 0s 280ms;
}

/* A list's choices come out of the button that opens them, as a tool's
   row does out of its tool (.replay-bar[data-away], below): put away,
   each lies under the button, small and unseen (`--away-x`, `--away-y`,
   from its place to the button's: my-clock.js placePanel), and opening
   the list slides them out to their places, fading in as they go, and
   closing it back the same way. */
.setting-options > * {
    transition: transform 280ms ease-in-out, opacity 200ms ease, visibility 0s;
}

.setting-control[data-open="false"] > .setting-options > * {
    opacity: 0;
    visibility: hidden;
    transform: translate(var(--away-x, 0px), var(--away-y, 0px)) scale(0.6);
    transition: transform 280ms ease-in-out, opacity 200ms ease 80ms, visibility 0s 280ms;
}

/* A row's own choices can be dragged across (my-clock.js enableRowScrub)
   rather than tapped one at a time, so the row itself must not scroll or
   swipe-navigate as a finger crosses it. */
.setting-options-row {
    touch-action: none;
}

/* A row's choices (face, speed) wear an icon alone: square, like the
   toolbar's own buttons, rather than a name padded out to fit. */
.setting-options-row .choice-button {
    display: grid;
    place-items: center;
    width: 42px;
    min-width: 0;
    height: 42px;
    min-height: 0;
    padding: 0;
}

/* A row's own list lies on a tray of frosted glass, the board seen
   through it, and so does a tool's own row (the stopwatch's, the
   gallery's, the replay's bar); the button whose row it is is dark on
   white, as the tool in use is, and wears a rim of the same glass
   joined to the tray, as a tab is to its page, so the choices are
   plainly that button's. The rim is exactly the gap between the button
   and its tray, and its corners on the tray's side are square
   (my-clock.js sets the button's `data-side`, and squares the tray's own
   corner where its edge meets the rim's: joinTray). In
   portrait the row lies flat rather than dropping down, and, the tray's
   padding allowed for (placePanel, my-clock.js), starts exactly under
   its button's place in the toolbar row and, its icons the same size
   and spacing, lands each one under the button that follows it there
   (see createSettingControl). Landscape keeps a column of icons beside
   the button like any other list, since there is no row of icons above
   to line up under. */
:root {
    --glass: rgb(255 255 255 / 0.2);
    --glass-blur: blur(10px) saturate(1.4);
    --rim: 6px;
    --fillet: 8px;
    /* The buttons as slabs with some thickness to them, lit, as the
       stones are, from up to the left: a catch of light along the top,
       their side showing a little below and to the right, and a small
       shadow cast that way. The tool in use, and an open setting, stand
       lifted off the rest, casting a deeper shadow further off; with its
       row out, the rim round it and the tray cast it instead, each cut
       off where they join (my-clock.js joinTray, for the tray), so that
       rim and tray lift as one sheet of glass with no shadow across it. */
    --slab: inset var(--lit-edge) 0 rgb(255 255 255 / 0.16), var(--fall-1-2) 0 rgb(0 0 0 / 0.55), var(--fall-2-4) 6px rgb(0 0 0 / 0.3);
    --slab-edge: inset var(--lit-edge) 0 rgb(255 255 255 / 0.16), var(--fall-1-2) 0 rgb(0 0 0 / 0.55);
    --lifted-shadow: var(--fall-5-10) 16px rgb(0 0 0 / 0.5);
    /* A button lying on a tray casts its shadow short, so that it stays
       on the glass, within the tray's rim, and never falls over the edge
       (or across the join). */
    --slab-on-glass: inset var(--lit-edge) 0 rgb(255 255 255 / 0.16), var(--fall-1-2) 0 rgb(0 0 0 / 0.55), var(--fall-1-2) 3px rgb(0 0 0 / 0.3);
}

.setting-options-row .choice-button,
.replay-bar > *,
.stopwatch-bar > *,
.gallery-bar > * {
    box-shadow: var(--slab-on-glass);
}

.setting-options-row .choice-button[aria-pressed="true"] {
    box-shadow: inset 0 0 0 2px rgb(255 255 255 / 0.92), var(--slab-on-glass);
}

.setting-options-row,
.replay-bar,
.stopwatch-bar,
.gallery-bar {
    padding: var(--rim);
    border-radius: 12px;
    background: var(--glass);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    box-shadow: var(--lifted-shadow);
}

.setting-options-row {
    gap: 6px;
}

.setting-control[data-open="true"] > .setting-summary:has(+ .setting-options-row),
.toolbar[data-collapsed="false"] .toolbar-actions > .setting-summary[aria-pressed="true"] {
    position: relative;
}

/* The tool in use lifted; and, with its row out (or an open setting's),
   its rim casting the shadow for it. */
.toolbar-actions .setting-summary[aria-pressed="true"] {
    box-shadow: var(--slab-edge), var(--lifted-shadow);
}

.setting-control[data-open="true"] > .setting-summary:has(+ .setting-options-row),
.toolbar[data-collapsed="false"] .toolbar-actions > .setting-summary[aria-pressed="true"] {
    box-shadow: var(--slab-edge);
}

/* The rim, and (::after) the fillets that flare it out into its tray
   on either side, as a tab's edge curves into its page. */
.setting-control[data-open="true"] > .setting-summary:has(+ .setting-options-row)::before,
.toolbar[data-collapsed="false"] .toolbar-actions > .setting-summary[aria-pressed="true"]::before,
.setting-control[data-open="true"] > .setting-summary:has(+ .setting-options-row)[data-side]::after,
.toolbar[data-collapsed="false"] .toolbar-actions > .setting-summary[aria-pressed="true"][data-side]::after {
    content: "";
    position: absolute;
    z-index: -1;
    background: var(--glass);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    pointer-events: none;
}

.setting-control[data-open="true"] > .setting-summary:has(+ .setting-options-row)::before,
.toolbar[data-collapsed="false"] .toolbar-actions > .setting-summary[aria-pressed="true"]::before {
    box-shadow: var(--lifted-shadow);
}

/* The rim rounded where it is free, and square on its tray's side
   (my-clock.js sets the button's `data-side`), which must win: so the
   rounding is on a rule of its own that says as little as it can. */
.setting-summary::before {
    inset: calc(-1*var(--rim));
    border-radius: 12px;
}

.setting-summary[data-side="below"]::before {
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    clip-path: inset(-40px -40px 0 -40px);
}

.setting-summary[data-side="above"]::before {
    border-top-left-radius: 0;
    border-top-right-radius: 0;
    clip-path: inset(0 -40px -40px -40px);
}

.setting-summary[data-side="right"]::before {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
    clip-path: inset(-40px 0 -40px -40px);
}

.setting-summary[data-side="left"]::before {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    clip-path: inset(-40px -40px -40px 0);
}

/* The fillets: a strip of glass along the edge where the rim meets the
   tray, reaching a fillet's width past the rim at each end, cut away
   by a quarter circle at each end and not drawn at all over the rim
   itself. One whose end of the tray runs on flush from the rim, or
   nearly (my-clock.js, joinTray), is sized to nothing: `--fillet-start`
   is the one at the left or top, `--fillet-end` the right or bottom. */
.setting-summary::after {
    --r: var(--fillet);
    --cut: transparent calc(var(--r) - 0.5px), black var(--r);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-size: var(--fillet-start, var(--r)) var(--fillet-start, var(--r)), var(--fillet-end, var(--r)) var(--fillet-end, var(--r));
    mask-size: var(--fillet-start, var(--r)) var(--fillet-start, var(--r)), var(--fillet-end, var(--r)) var(--fillet-end, var(--r));
}

.setting-summary[data-side="below"]::after,
.setting-summary[data-side="above"]::after {
    left: calc(-1*var(--rim) - var(--r));
    right: calc(-1*var(--rim) - var(--r));
    height: var(--r);
}

.setting-summary[data-side="right"]::after,
.setting-summary[data-side="left"]::after {
    top: calc(-1*var(--rim) - var(--r));
    bottom: calc(-1*var(--rim) - var(--r));
    width: var(--r);
}

.setting-summary[data-side="below"]::after {
    bottom: calc(-1*var(--rim));
    -webkit-mask-image: radial-gradient(circle at 0 0, var(--cut)), radial-gradient(circle at 100% 0, var(--cut));
    mask-image: radial-gradient(circle at 0 0, var(--cut)), radial-gradient(circle at 100% 0, var(--cut));
    -webkit-mask-position: left bottom, right bottom;
    mask-position: left bottom, right bottom;
}

.setting-summary[data-side="above"]::after {
    top: calc(-1*var(--rim));
    -webkit-mask-image: radial-gradient(circle at 0 100%, var(--cut)), radial-gradient(circle at 100% 100%, var(--cut));
    mask-image: radial-gradient(circle at 0 100%, var(--cut)), radial-gradient(circle at 100% 100%, var(--cut));
    -webkit-mask-position: left top, right top;
    mask-position: left top, right top;
}

.setting-summary[data-side="right"]::after {
    right: calc(-1*var(--rim));
    -webkit-mask-image: radial-gradient(circle at 0 0, var(--cut)), radial-gradient(circle at 0 100%, var(--cut));
    mask-image: radial-gradient(circle at 0 0, var(--cut)), radial-gradient(circle at 0 100%, var(--cut));
    -webkit-mask-position: right top, right bottom;
    mask-position: right top, right bottom;
}

.setting-summary[data-side="left"]::after {
    left: calc(-1*var(--rim));
    -webkit-mask-image: radial-gradient(circle at 100% 0, var(--cut)), radial-gradient(circle at 100% 100%, var(--cut));
    mask-image: radial-gradient(circle at 100% 0, var(--cut)), radial-gradient(circle at 100% 100%, var(--cut));
    -webkit-mask-position: left top, left bottom;
    mask-position: left top, left bottom;
}

/* While a row of choices is out, the rest of the buttons in the row its
   button is in stand back, so the button and its tray stand out
   together: the board's settings, and the toolbar's tools, whose tool
   in use has its row out whenever the toolbar is (bar the clock, whose
   faces can be put away). */
.board-actions:has(> .setting-control[data-open="true"]) > :not(.setting-control[data-open="true"]),
.toolbar[data-collapsed="false"] .toolbar-actions:has(> .setting-control[data-open="true"], > .setting-summary[aria-pressed="true"]) > :not(.setting-control[data-open="true"], [aria-pressed="true"]) {
    opacity: 0.55;
}

@media (orientation: portrait) {
    .setting-options-row {
        display: flex;
        grid-template-columns: none;
    }
}

.choice-button {
    display: grid;
    width: 100%;
    min-width: 34px;
    min-height: 32px;
    padding: 0 10px;
    border: 0;
    border-radius: 4px;
    justify-items: start;
    align-items: center;
    /* The same dark the toolbar's own buttons wear, and the same slab:
       only the one picked (aria-pressed) stands out, ringed in white. */
    background: rgb(0 0 0 / 0.7);
    color: white;
    cursor: pointer;
    font: 700 13px/1 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    white-space: nowrap;
    box-shadow: var(--slab);
}

/* The choice made: ringed in white, on the same dark as the rest. */
.choice-button[aria-pressed="true"] {
    box-shadow: inset 0 0 0 2px rgb(255 255 255 / 0.92), var(--slab);
}

.setting-control[data-open="true"] > .submenu-button {
    background: rgb(255 255 255 / 0.93);
    color: #261917;
}

/* A submenu's button: its name, the current choice, and an arrow; and,
   where its choices have icons, the icon of the current one before them. */
.submenu-button {
    grid-template-columns: max-content max-content;
    gap: 8px;
}

.submenu-with-icon {
    grid-template-columns: 22px max-content max-content;
    padding-left: 6px;
}

.submenu-button .setting-value {
    font-weight: 400;
    opacity: 0.8;
}

.submenu-button .setting-value::after {
    content: " ›";
    font-weight: 700;
}

.choice-button:focus-visible {
    background: rgb(0 0 0 / 0.8);
    outline: 2px solid rgb(255 255 255 / 0.82);
    outline-offset: -2px;
}

.button:focus-visible {
    background: rgb(0 0 0 / 0.78);
    outline: 2px solid rgb(255 255 255 / 0.8);
    outline-offset: -2px;
}

/* The replayed game's kifu (kifu-card.js, which places and turns it,
   and sets its shadow to fall down and to the right whichever way it
   lies): a sheet of paper held up close to the eye, over everything,
   printed as a score sheet in red ink and written up by hand. Unseen
   until it is brought up. Behind it, all the rest out of focus, and a
   little darker, fading in and out as it comes and goes; a tap there
   puts it away. Above the sweep's arm (100), the highest of what is on
   the board, so that no stone comes up through it. */
.kifu-backdrop {
    position: fixed;
    inset: 0;
    z-index: 200;
    background: rgb(12 8 4 / 0.14);
    -webkit-backdrop-filter: blur(2.5px);
    backdrop-filter: blur(2.5px);
    opacity: 0;
    visibility: hidden;
    transition: opacity 380ms ease-in, visibility 0s 380ms;
}

.kifu-backdrop.out {
    opacity: 1;
    visibility: visible;
    transition: opacity 500ms ease-out, visibility 0s;
}

.kifu {
    --kifu-red: #a8432c;
    --kifu-ink: #1d1a17;
    --kifu-printed: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
    --kifu-hand: "Bradley Hand", "Segoe Print", "Chalkboard SE", cursive;
    position: fixed;
    left: 0;
    top: 0;
    z-index: 201;
    box-sizing: border-box;
    padding: 16px 16px 14px;
    border-radius: 2px;
    color: var(--kifu-ink);
    background-color: #f3ead6;
    background-size: 256px;
    touch-action: none;
    cursor: grab;
    visibility: hidden;
    -webkit-user-select: none;
    user-select: none;
}

.kifu.out {
    visibility: visible;
    will-change: transform;
}

.kifu.held {
    cursor: grabbing;
}

/* The light over the sheet, a touch darker to its far corner. */
.kifu::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: linear-gradient(160deg, rgb(255 255 255 / 0.18), rgb(0 0 0 / 0) 45%, rgb(80 50 20 / 0.08));
    pointer-events: none;
}

.kifu-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    padding-bottom: 5px;
    border-bottom: 1.5px solid var(--kifu-red);
    color: var(--kifu-red);
    font: 600 11px/1 var(--kifu-printed);
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

.kifu-kanji {
    font-size: 14px;
    letter-spacing: 0.3em;
}

.kifu-title {
    margin: 9px 0 1px;
    font: 600 17px/1.2 var(--kifu-printed);
}

.kifu-event {
    min-height: 1em;
    font: italic 12.5px/1.3 var(--kifu-printed);
    opacity: 0.75;
}

.kifu-rows {
    margin-top: 8px;
    border-top: 0.75px solid rgb(168 67 44 / 0.55);
}

.kifu-row {
    position: relative;
    display: grid;
    grid-template-columns: 58px 1fr;
    align-items: baseline;
    gap: 6px;
    padding: 4px 0 3px;
    border-bottom: 0.75px solid rgb(168 67 44 / 0.55);
}

.kifu-row[hidden] {
    display: none;
}

.kifu-label {
    display: flex;
    align-items: center;
    gap: 5px;
    color: var(--kifu-red);
    font: 600 9.5px/1 var(--kifu-printed);
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.kifu-value {
    min-width: 0;
    font: 15px/1.25 var(--kifu-hand);
    overflow-wrap: anywhere;
}

/* Room beside the winner's name for their seal. */
.kifu-row.won > .kifu-value {
    padding-right: 40px;
}

.kifu-rank {
    margin-left: 0.4em;
    opacity: 0.7;
}

.kifu-mark {
    width: 9px;
    height: 9px;
    box-sizing: border-box;
    border: 1.2px solid var(--kifu-ink);
    border-radius: 50%;
}

.kifu-mark.black {
    background: var(--kifu-ink);
}

.kifu-record {
    display: block;
    width: 100%;
    margin-top: 10px;
    aspect-ratio: 1;
}

.kifu-caption {
    margin-top: 3px;
    color: var(--kifu-red);
    font: 9.5px/1 var(--kifu-printed);
    letter-spacing: 0.1em;
    text-align: right;
    text-transform: uppercase;
}

/* The winner's seal, stamped over their line in red ink. */
.kifu-seal {
    position: absolute;
    right: -4px;
    top: 50%;
    display: grid;
    place-items: center;
    width: 42px;
    height: 42px;
    margin-top: -21px;
    box-sizing: border-box;
    border: 2.5px solid rgb(180 38 26 / 0.82);
    border-radius: 50%;
    color: rgb(180 38 26 / 0.85);
    font: 700 12px/1 var(--kifu-printed);
    letter-spacing: -0.02em;
    transform: rotate(-14deg);
    mix-blend-mode: multiply;
    pointer-events: none;
}

.kifu-seal::before {
    content: "";
    position: absolute;
    inset: 2px;
    border: 0.75px solid currentColor;
    border-radius: 50%;
}

/* The replay's bar: play or pause, next to the line of the game with a
   marker on it, in the row beneath the toolbar's from under the replay
   button, or beside that button running down in landscape (see the media
   query below). In the dress of the toolbar's own icons: the play button
   is one, square under the replay button, and the line is one long one,
   as tall as they are. Below the toolbar and its open lists (z-index there
   is 20), so a list dropped open never finds the bar sitting over it.
   my-clock.js places it against the replay button and the board;
   [hidden] takes it off the screen when no game is running, and, while one
   is, it fades with the toolbar's own row when that is tucked away or
   brought back (it is not itself a member of that row, so the CSS keys
   off the toolbar's data-collapsed rather than the usual rule). */
.replay-bar,
.stopwatch-bar,
.gallery-bar {
    position: fixed;
    z-index: 15;
    display: flex;
    align-items: center;
    gap: 6px;
    color: white;
    transition: opacity 200ms ease, visibility 0s;
}

.toolbar[data-collapsed="true"] ~ #replay-bar,
.toolbar[data-collapsed="true"] ~ #stopwatch-bar,
.toolbar[data-collapsed="true"] ~ #gallery-bar {
    visibility: hidden;
    opacity: 0;
    transition: opacity 200ms ease, visibility 0s 280ms;
}

/* A tool's row that is away (my-clock.js showToolBar, hideToolBar): its
   buttons each under the tool's own button, and unseen, so that they
   slide out from under it as the tool is picked, and back under it as
   another is; the tray fades with them. */
.replay-bar[data-away="true"],
.stopwatch-bar[data-away="true"],
.gallery-bar[data-away="true"] {
    opacity: 0;
}

.replay-bar[data-away="true"] > *,
.stopwatch-bar[data-away="true"] > *,
.gallery-bar[data-away="true"] > * {
    opacity: 0;
    transform: translate(var(--away-x, 0px), var(--away-y, 0px)) scale(0.6);
}

/* A bar's buttons come out with the toolbar's row and go back with it,
   as the faces do (.setting-options-row, below): each slides from under
   the toggle to its place, `--back` px (my-clock.js placeToolBar), and
   back again, fading as it arrives. */
.replay-bar > *,
.stopwatch-bar > *,
.gallery-bar > * {
    transition: transform 280ms ease-in-out, opacity 200ms ease;
}

.toolbar[data-collapsed="true"] ~ #replay-bar > *,
.toolbar[data-collapsed="true"] ~ #stopwatch-bar > *,
.toolbar[data-collapsed="true"] ~ #gallery-bar > * {
    opacity: 0;
    transform: translateX(calc(-1*var(--back, 0px)));
    transition: transform 280ms ease-in-out, opacity 200ms ease 80ms;
}

.replay-track {
    /* How far in from each end the line runs, and the marker's middle
       at its first and last move: its own width clear of the ends. */
    --track-inset: 18px;
    position: relative;
    flex: 1;
    align-self: stretch;
    min-width: 42px;
    min-height: 42px;
    border-radius: 6px;
    background: rgb(0 0 0 / 0.7);
    box-shadow: var(--slab);
    cursor: pointer;
    touch-action: none;
}

.replay-track:focus-visible {
    outline: 2px solid rgb(255 255 255 / 0.8);
    outline-offset: -2px;
    border-radius: 6px;
}

.replay-line {
    position: absolute;
    top: 50%;
    right: var(--track-inset);
    left: var(--track-inset);
    height: 3px;
    border-radius: 2px;
    /* The moves played, from the start up to the marker, filled in, so
       that which end the game began at shows whichever way up the phone
       is held. */
    background: linear-gradient(var(--line-way, to right),
        white calc(var(--progress, 0)*100%), rgb(255 255 255 / 0.35) calc(var(--progress, 0)*100%));
    transform: translateY(-50%);
}

/* The marker a pointer, the way the game goes: a bold chevron, not a
   play button's triangle, so that it is not taken for one pointing the
   other way when the phone is upside down; its shadow falling as the
   light does (`--turn`). */
.replay-marker {
    position: absolute;
    top: 50%;
    left: calc(var(--track-inset) + (100% - 2*var(--track-inset))*var(--progress, 0));
    width: 18px;
    height: 18px;
    transform: translate(-50%, -50%);
    filter: drop-shadow(var(--fall-0-2) 3px rgb(0 0 0 / 0.5));
    pointer-events: none;
}

.replay-marker svg {
    display: block;
    width: 100%;
    height: 100%;
    fill: none;
    stroke: white;
    stroke-width: 3.5;
    stroke-linecap: round;
    stroke-linejoin: round;
    rotate: var(--marker-way, 0deg);
}

/* The stopwatch's own row (index.html): start or stop, and reset, placed
   and shown as the replay's bar is (above), but only as long as its two
   buttons. Reset is there while the stopwatch runs, as it is on one, but
   greyed out: only a stopped stopwatch can be put back to nothing. */
.setting-summary:disabled {
    cursor: default;
    opacity: 0.35;
}

/* A narrow phone: the row of buttons a little tighter, so it fits in one,
   and a row's own choices (above) shrink and close up the same way, to
   keep landing under the buttons that follow them. */
@media (orientation: portrait) and (max-width: 400px) {
    .toolbar,
    .toolbar-actions,
    .setting-options-row {
        gap: 4px;
    }

    .replay-bar,
    .stopwatch-bar,
    .gallery-bar,
    .board-control,
    .board-actions {
        gap: 4px;
    }

    .replay-track {
        min-height: 38px;
    }

    .menu-toggle,
    .toolbar .setting-summary,
    .board-control .setting-summary,
    .replay-bar .setting-summary,
    .stopwatch-bar .setting-summary,
    .gallery-bar .setting-summary {
        width: 38px;
        min-height: 38px;
    }

    .menu-toggle {
        height: 38px;
    }

    .setting-options-row .choice-button {
        width: 38px;
        height: 38px;
    }

}

/* Landscape: the board leaves the sides free, so the buttons run down the
   left, the toggle at the top, and a setting's choices open out to its
   right. */
@media (orientation: landscape) {
    .toolbar {
        flex-direction: column;
        align-items: flex-start;
        max-width: none;
        max-height: calc(100vh - 20px - env(safe-area-inset-top) - env(safe-area-inset-bottom));
    }

    .toolbar-actions {
        flex-direction: column;
        flex-wrap: nowrap;
        align-items: flex-start;
    }

    .toolbar[data-collapsed="true"] .toolbar-actions > * {
        top: calc(var(--i) * -48px - var(--close-size) - 6px);
        left: 0;
    }

    /* The cross, smaller than the column's buttons, centred over them. */
    .toolbar .menu-toggle {
        align-self: center;
    }

    .replay-bar,
    .stopwatch-bar,
    .gallery-bar {
        flex-direction: column;
    }

    .toolbar[data-collapsed="true"] ~ #replay-bar > *,
    .toolbar[data-collapsed="true"] ~ #stopwatch-bar > *,
    .toolbar[data-collapsed="true"] ~ #gallery-bar > * {
        transform: translateY(calc(-1*var(--back, 0px)));
    }

    .replay-line {
        top: var(--track-inset);
        right: 50%;
        bottom: var(--track-inset);
        left: 50%;
        width: 3px;
        height: auto;
        transform: translateX(-50%);
    }

    .replay-track {
        --line-way: to bottom;
        --marker-way: 90deg;
    }

    .replay-marker {
        top: calc(var(--track-inset) + (100% - 2*var(--track-inset))*var(--progress, 0));
        left: 50%;
    }
}

/* Hover styles only where something can hover: on iOS a :hover rule makes
   the first tap a hover and only the second a click. */
@media (hover: hover) {
    .setting-summary:hover {
        background: rgb(0 0 0 / 0.8);
        outline: 2px solid rgb(255 255 255 / 0.8);
        outline-offset: -2px;
    }

    .setting-control[data-open="true"] > .setting-summary:hover {
        background: white;
    }

    .setting-summary:disabled:hover {
        background: rgb(0 0 0 / 0.7);
        outline: none;
    }

    .choice-button:hover {
        background: rgb(0 0 0 / 0.8);
        outline: 2px solid rgb(255 255 255 / 0.82);
        outline-offset: -2px;
    }

    .choice-button[aria-pressed="true"]:hover {
        background: white;
    }

    .button:hover {
        background: rgb(0 0 0 / 0.78);
        outline: 2px solid rgb(255 255 255 / 0.8);
        outline-offset: -2px;
    }
}

/* The board turned over (board-flip.js): while it is, and while it turns,
   a board in three dimensions over the one on the page, which is hidden,
   and its stones with it; seen from two board widths above, the board
   and the stones in the one space. Over the goban, under the menus. */
.board-flip {
    position: absolute;
    z-index: 3;
    overflow: hidden;
    touch-action: none;
}

.board-flip-shadow,
.board-flip-splashes,
.board-splash {
    position: absolute;
    left: 0;
    top: 0;
    pointer-events: none;
}

.board-flip-splashes {
    inset: 0;
    /* Its ripples' and drops' own z-index kept within it: the rings under
       the board, and the spray, the layer after the board, over it. */
    isolation: isolate;
}

.board-flip-world,
.board-flip-box {
    position: absolute;
    transform-style: preserve-3d;
    -webkit-transform-style: preserve-3d;
}

.board-flip-world {
    inset: 0;
}

.board-flip-face {
    position: absolute;
    overflow: hidden;
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
}

.board-flip-wood,
.board-flip-shade {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
}

/* The computer board's edges and underside, or a picture that could not
   be read: its colour, plain. */
.board-flip-wood.plain {
    background: #dcb35c;
}

/* The board turned over, lying on the page (board-flip.js toPage): its
   underside and the writing on it over the board's picture, under its
   stones; and the splash's drops on the board, wetting it (WetSpots). */
.board-underside {
    position: absolute;
    z-index: 0;
    overflow: hidden;
    pointer-events: none;
}

.wet-spots {
    position: absolute;
    pointer-events: none;
}

/* Each face's light: black over it, as dark as the face is turned from
   the light. */
.board-flip-shade {
    background: black;
    opacity: 0;
}

.board-flip-stone,
.board-flip-stone-shadow {
    position: absolute;
    left: 0;
    top: 0;
    pointer-events: none;
}

.board-flip-stone {
    background-size: 100% 100%;
    background-repeat: no-repeat;
}

/* A tumbling stone wears a frame of its tumble sheet (flight.js). */
.board-flip-stone.flying {
    background-size: 600% 300%;
}

.board-flip-stone-shadow {
    border-radius: 50%;
    background: radial-gradient(closest-side, rgb(0 0 0 / 0.7), rgb(0 0 0 / 0.45) 55%, rgb(0 0 0 / 0));
}

/* What is written on the underside of the board (index.html): in ink
   soaking into the grain, the right way up for the board turned over
   end over end from portrait (board-flip.js), and sized to the board (its font size is a 27th of the board's width, set by
   board-flip.js). */
#about_box {
    position: absolute;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 0 11%;
    color: rgb(38 24 12);
    mix-blend-mode: multiply;
    font-family: "Iowan Old Style", "Palatino", "Georgia", serif;
    line-height: 1.45;
    text-align: center;
}

#about_box h1 {
    margin: 0 0 0.9em;
    font-size: 1.5em;
    font-weight: 400;
    line-height: 1;
    letter-spacing: 0.02em;
}

#about_box h1 strong {
    display: block;
    font-size: 2.9em;
    font-weight: 700;
    line-height: 0.95;
}

#about_box p {
    margin: 0 0 0.9em;
}

.about-tip {
    font-style: italic;
}

/* A maker's seal, in red, as a board maker stamps the underside. */
.about-seal {
    align-self: center;
    display: grid;
    place-items: center;
    width: 2.6em;
    height: 2.6em;
    margin-top: 0.7em;
    border: 0.14em solid rgb(170 30 20 / 0.85);
    border-radius: 0.2em;
    color: rgb(170 30 20 / 0.85);
    font-family: "Hiragino Mincho ProN", "Yu Mincho", serif;
    font-size: 1.1em;
    line-height: 1;
    transform: rotate(-3deg);
}

.about-seal span {
    font-size: 1.7em;
}

.about-meta {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    margin: 1.4em 0 0;
    font-size: 0.8em;
    opacity: 0.85;
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        scroll-behavior: auto !important;
        transition-duration: 1ms !important;
        animation-duration: 1ms !important;
    }
}

/* Sits exactly where the toolbar does, unseen, for my-clock.js to hear
   when that moves: the safe area can arrive after the first layout. */
.toolbar-place {
    position: fixed;
    top: 0;
    left: 0;
    width: max(10px, env(safe-area-inset-left));
    height: max(10px, env(safe-area-inset-top));
    visibility: hidden;
    pointer-events: none;
}
