/* Layout: one empty screen, the name dead centre, one sentence beneath it, a clock line in the corner. Everything else is behaviour. */
:root {
  --bg: #FFFFFF;
  --fg: #111111;
  --faint: #666662;
  --shade: #8F8F8B;
  --name: "Newsreader", "Iowan Old Style", Georgia, serif;
  --t: .4s;
  --ease: cubic-bezier(.65, 0, .2, 1);
}
/* Dark when the viewer's system is dark, or when it is night in Toronto. An explicit theme choice always wins. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not(.day) { --bg: #0C0C0C; --fg: #F2F2F0; --faint: #9A9A96; --shade: #7C7C78; color-scheme: dark }
}
:root[data-theme="dark"], :root.night:not([data-theme="light"]) { --bg: #0C0C0C; --fg: #F2F2F0; --faint: #9A9A96; --shade: #7C7C78; color-scheme: dark }

* { box-sizing: border-box }
html, body { height: 100% }
body { background: var(--bg); color: var(--fg); font-family: var(--name); font-size: 1rem; transition: background-color .8s ease, color .8s ease }
.page { height: 100%; min-height: 22rem; display: grid; place-items: center; overflow: hidden; touch-action: none; user-select: none; -webkit-user-select: none; padding-left: max(16px, env(safe-area-inset-left, 0px)); padding-right: max(16px, env(safe-area-inset-right, 0px)); padding-block: 1rem }
.centre { display: flex; flex-direction: column; align-items: center; gap: .9rem; min-width: 0; max-width: 100%; position: relative; z-index: 2 }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap }

.name { background: none; border: 0; margin: 0; padding: .15em 1.7em; color: var(--fg); cursor: pointer; font-family: var(--name); font-weight: 400; font-size: clamp(1.9rem, 6.2vw, 5.5rem); line-height: 1.05; letter-spacing: -.025em; white-space: nowrap; transition: transform .35s cubic-bezier(.2, .8, .2, 1) }
.name:focus-visible { outline: 1px solid var(--faint); outline-offset: 2px }
.core { position: relative; display: inline-block; transition: transform .14s ease-out }
.name.press .core { transform: translateY(2px) scale(.985) }

/* Capitals roll to lowercase while hi@ and .ca arrive and the gap closes. */
.pre, .post { position: absolute; top: 0; opacity: 0; transform: perspective(6em) rotateX(-90deg); transform-origin: 50% 55% -.42em; backface-visibility: hidden; transition: transform var(--t) var(--ease), opacity var(--t) ease; transition-delay: .25s }
.pre { right: 100% } .post { left: 100% }
.gap { display: inline-block; width: .22em; transition: width .25s var(--ease) 0s }
.sw { display: inline-block; position: relative; width: var(--wu, auto); transition: width .25s var(--ease) 0s }
.sw .u, .sw .l { display: inline-block; transform-origin: 50% 55% -.42em; backface-visibility: hidden; transition: transform var(--t) var(--ease), opacity var(--t) ease; transition-delay: .25s }
.sw .u { transform: none; opacity: 1 }
.sw .l { position: absolute; left: 0; top: 0; transform: perspective(6em) rotateX(-90deg); opacity: 0 }
.page.mail .pre, .page.mail .post { opacity: 1; transform: none; transition-delay: 0s }
.page.mail .gap { width: 0; transition-delay: var(--t) }
.page.mail .sw { width: var(--wl, auto); transition-delay: var(--t) }
.page.mail .sw .u { transform: perspective(6em) rotateX(90deg); opacity: 0; transition-delay: 0s }
.page.mail .sw .l { transform: none; opacity: 1; transition-delay: 0s }

/* The same drum, reused for the sentence, the cycling word and the clock. */
@keyframes rollIn { from { transform: perspective(6em) rotateX(-90deg); opacity: 0 } to { transform: none; opacity: 1 } }
@keyframes rollOut { from { transform: none; opacity: 1 } to { transform: perspective(6em) rotateX(90deg); opacity: 0 } }
.roll-in { animation: rollIn var(--t) var(--ease) both }
.roll-out { animation: rollOut var(--t) var(--ease) both }
/* The hint line is dropped from the name: a short fall, a hard stop, a one-pixel settle. */
@keyframes dropIn { from { transform: translateY(-3px); opacity: 0 } to { transform: translateY(0); opacity: 1 } }
@keyframes fadeIn { from { opacity: 0 } to { opacity: 1 } }
@keyframes fadeOut { from { opacity: 1 } to { opacity: 0 } }
.drop-in { animation: dropIn .3s ease-out both }
.fade-in { animation: fadeIn .25s ease both }
.fade-out { animation: fadeOut .15s ease both }
@media (prefers-reduced-motion: reduce) { .drop-in, .fade-in { animation: none } .fade-out { animation: none; opacity: 0 } }

.sub { display: grid; place-items: center; color: var(--faint); font-size: clamp(.95rem, 1.5vw, 1.15rem); line-height: 1.35; margin: 0; user-select: text; -webkit-user-select: text }
.face { grid-area: 1 / 1; display: block; white-space: nowrap; transform-origin: 50% 55% -.42em }
.slot { display: inline-block; position: relative; text-align: left }
.word { position: absolute; left: 0; top: 0; display: inline-block; white-space: nowrap; color: var(--fg); transform-origin: 50% 55% -.42em }

.clock { position: fixed; z-index: 2; left: max(20px, env(safe-area-inset-left, 0px)); bottom: calc(18px + env(safe-area-inset-bottom, 0px)); margin: 0; color: var(--faint); font-size: .85rem; pointer-events: none }
.clock { display: grid; justify-items: start }
.clock span { grid-area: 1 / 1; display: inline-block; white-space: nowrap; transform-origin: 50% 55% -.42em }

.toast { position: fixed; z-index: 2; right: max(20px, env(safe-area-inset-right, 0px)); bottom: calc(18px + env(safe-area-inset-bottom, 0px)); margin: 0; color: var(--faint); font-size: .85rem; cursor: pointer; user-select: text; -webkit-user-select: text; opacity: 0; transition: opacity .3s ease; display: grid; justify-items: end }
.toast.on { opacity: 1 }
.toast span { grid-area: 1 / 1; display: inline-block; white-space: nowrap; transform-origin: 50% 55% -.42em }

#ride { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 1; pointer-events: none }

/* Hidden street game: the card steps aside while it runs. */
.centre { transition: opacity .5s ease, transform .5s ease }
.page.game .centre { opacity: 0; transform: translateX(-48px); visibility: hidden; pointer-events: none; transition: opacity .35s ease, transform .35s ease, visibility 0s .35s }
.page.game .toast { opacity: 0; visibility: hidden; pointer-events: none }
/* iPhone: a long press must not raise the text magnifier, selection handles or a callout while playing or drawing */
.page { -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent }
.page.game, .page.game * { user-select: none !important; -webkit-user-select: none !important; -webkit-touch-callout: none !important }

@media (prefers-reduced-motion: reduce) {
  .pre, .post, .gap, .sw, .sw .u, .sw .l, .name, .core, .slot, body { transition: none !important }
  .roll-in { animation: none } .roll-out { animation: none; opacity: 0 }
}

/* the arrival: name, then the sentence, then the corners. A failsafe shows everything after 2.5 s if the script never runs. */
@keyframes arrive { from { opacity: 0; transform: translateY(6px) } to { opacity: 1; transform: none } }
@keyframes failsafe { to { opacity: 1 } }
html:not(.go) .name, html:not(.go) .sub, html:not(.go) .clock, html:not(.go) .toast { opacity: 0; animation: failsafe 0s 2.5s forwards }
.go .name { animation: arrive 1s cubic-bezier(.22, .7, .2, 1) .15s backwards }
.go .sub { animation: arrive 1s cubic-bezier(.22, .7, .2, 1) .7s backwards }
.go .clock, .go .toast { animation: arrive 1s cubic-bezier(.22, .7, .2, 1) 1.35s backwards }
@media (prefers-reduced-motion: reduce) { .go .name, .go .sub, .go .clock, .go .toast { animation: none } }
