/* App screens (stories, join, home), ported from the hi-fi prototype
   (design/prototype). Every value comes from the design system tokens. */
.screen {
  max-width: 480px;
  min-height: 100dvh;
  margin: 0 auto;
  padding: var(--space-6) 18px 24px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  /* A long word breaks rather than pushing the screen wider (a larger text size) */
  overflow-wrap: anywhere;
}

.bar { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 32px; }
.bar .af-pill { margin-left: auto; }
.back { display: inline-flex; align-items: center; gap: 4px; color: var(--ballpoint); font-weight: 500; font-size: calc(15rem / 17); text-decoration: none; }
.icon-btn { width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; border: 1px solid var(--line); background: var(--panel); color: var(--ink); font: inherit; cursor: pointer; box-shadow: var(--shadow-card); }

.intro { display: grid; gap: 6px; }
.title { margin: 0; font-family: var(--font-serif); font-weight: 400; font-size: calc(32rem / 17); line-height: 1.1; text-wrap: balance; }
.sub { margin: 0; color: var(--pencil); font-size: calc(14rem / 17); }
.sub.small { font-size: calc(12.5rem / 17); }
.row { display: flex; align-items: center; gap: 10px; }
.spacer { flex: 1; }

/* How long is this story? */
.kind-q { margin: 0; font-family: var(--font-serif); font-weight: 400; font-size: calc(36rem / 17); line-height: 1.1; }
a.af-story, a.af-btn { text-decoration: none; }

/* New story */
.setting { background: var(--panel); border: 1px solid var(--line); border-radius: 12px; box-shadow: var(--shadow-card); }
.setting summary { display: flex; align-items: center; gap: 12px; padding: 12px 14px; cursor: pointer; list-style: none; }
.setting summary::-webkit-details-marker { display: none; }
.setting-text { display: grid; flex: 1; }
.setting-text b { font-weight: 600; }
.setting-text .sub { font-size: calc(13rem / 17); }
.setting[open] summary .af-link { visibility: hidden; }
.setting-inputs { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; padding: 0 14px 14px; }
.sticky-foot { position: sticky; bottom: 0; margin: auto -18px -24px; padding: 14px 18px 22px; background: linear-gradient(to top, var(--page) 70%, transparent); display: grid; gap: 8px; }

/* People */
.faces { display: flex; }
.faces .af-face { border: 2px solid var(--page); margin-left: -8px; }
.faces .af-face:first-child { margin-left: 0; }
.af-face { background: #3F7B8C; }
.people-list { list-style: none; margin: 0; padding: 0; display: grid; }
.people-list li { display: flex; align-items: center; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--line); }
.people-list li > span:not(.af-face) { flex: 1; }
.people-list .remove { margin: 0; }


/* Join */
.join-wordmark { width: 110px; height: auto; display: block; }
.cover-prints { padding: 6px 8px 14px; }
.af-print-img.hatch { aspect-ratio: 4/5; border-radius: 1px; border: 0; }
.promise { display: grid; gap: 8px; font-size: calc(14rem / 17); }
.promise div { display: grid; grid-template-columns: 22px 1fr; gap: 8px; }
.promise i { font-style: normal; color: var(--ballpoint); font-weight: 700; }
.foot { margin-top: auto; display: grid; gap: 10px; }
.foot form { margin: 0; }
/* Get the app (invite page, iPhone and iPad): the steps are a real sequence, numbered in mono like a label. */
.get-app ol { margin: 0; padding: 0; list-style: none; display: grid; gap: 10px; counter-reset: step; }
.get-app li { display: grid; grid-template-columns: 22px 1fr; gap: 8px; font-size: calc(14rem / 17); color: var(--ink); counter-increment: step; }
.get-app li::before { content: counter(step); font-family: var(--font-mono); font-size: calc(12rem / 17); font-weight: 500; color: var(--ballpoint); padding-top: 1px; }
.get-app li a { font-weight: 600; }
.get-app .sub.small { margin: 0; }

/* Home */
.home-wm { width: 132px; height: auto; display: block; }
.now-card { display: grid; gap: 12px; background: var(--panel); border: 1px solid var(--line); border-radius: 18px; padding: 14px; color: var(--ink); text-decoration: none; box-shadow: var(--shadow-card); }
.now-card .strip { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; }
.now-card .strip > * { aspect-ratio: 1; }
.now-name { font-family: var(--font-serif); font-weight: 400; font-size: calc(22rem / 17); }
.list { display: grid; gap: 4px; }
.list-item { display: grid; grid-template-columns: 52px 1fr auto; gap: 14px; align-items: center; min-height: 64px; padding: 6px 0; border-bottom: 1px solid var(--line); color: var(--ink); text-decoration: none; }
.list-item > .hatch { width: 44px; height: 44px; }
.list-item b { display: block; }
/* A past story: two of its photos as small tilted prints (the design system's Prints, scaled down) */
.past-prints { position: relative; display: block; width: 52px; height: 44px; padding: 0; }
.past-prints .af-print { position: absolute; width: 30px; margin: 0; padding: 2px 2px 6px; }
.past-prints .af-print:first-child { left: 2px; top: 6px; }
.past-prints .af-print:nth-child(2) { left: 18px; top: 2px; margin: 0; }
.past-prints .af-print-img { width: 100%; height: auto; aspect-ratio: 1; object-fit: cover; }
.hatch { border-radius: 8px; border: 1px dashed var(--line-strong); background: repeating-linear-gradient(-45deg, var(--tray) 0 6px, var(--tray-stripe) 6px 12px); }

/* Toast (the design system's), at the bottom of the screen */
.toast { position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%); margin: 0; max-width: calc(100% - 36px); z-index: 10; }

/* The design system's DateRange, inside a setting */
.setting-body { padding: 0 14px 14px; }

/* Photos */
.add-photos { display: grid; gap: 10px; margin: 0; }
.photos-section { display: grid; gap: 8px; }
.photo-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; }
a.af-tile { display: block; }
.af-tile img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.dev-tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
/* Someone adding photos right now (Membership#adding?): blank prints, still
   hatched, land one after another in the top third of their tile; the count
   and the name sit below them, never under them. The border turns ballpoint.
   Still, the three prints lie stacked. */
.af-dev-adding { position: relative; overflow: hidden; place-content: end center; padding-bottom: 9%; border-style: solid; border-color: var(--ballpoint); }
.af-dev-drops { position: absolute; left: 0; right: 0; top: 6%; height: 34%; }
.af-dev-drops i { position: absolute; left: 50%; top: 0; height: 100%; aspect-ratio: 4 / 5; padding: 2px 2px 5px; border-radius: 2px; background: var(--panel); box-shadow: var(--shadow-print); transform: translateX(-50%) rotate(var(--tilt)); }
.af-dev-drops i::before { content: ""; display: block; height: 100%; background: repeating-linear-gradient(-45deg, var(--tray) 0 3px, var(--tray-stripe) 3px 6px); }
@media (prefers-reduced-motion: no-preference) {
  .af-dev-drops i { opacity: 0; animation: af-dev-drop 1.6s cubic-bezier(.16, 1, .3, 1) infinite; }
  .af-dev-drops i:nth-child(2) { animation-delay: .53s; }
  .af-dev-drops i:nth-child(3) { animation-delay: 1.06s; }
  @keyframes af-dev-drop {
    0% { opacity: 0; transform: translate(-50%, -90%) rotate(-10deg); }
    25% { opacity: 1; }
    55%, 85% { opacity: 1; transform: translateX(-50%) rotate(var(--tilt)); }
    100% { opacity: 0; transform: translateX(-50%) rotate(var(--tilt)); }
  }
}
.moment { display: grid; gap: 8px; }
.moment-head { display: flex; align-items: baseline; gap: 8px; }
.moment-head h2 { margin: 0; font-family: var(--font-serif); font-weight: 400; font-size: calc(20rem / 17); }
.moment-head small { margin-left: auto; color: var(--pencil); font-family: var(--font-mono); font-size: calc(12rem / 17); }
/* Arrived since you last looked (a live story): a ballpoint dot on the photo */
.af-tile.is-new::after { content: ""; position: absolute; left: 6px; top: 6px; width: 10px; height: 10px; border-radius: 50%; background: var(--ballpoint); box-shadow: 0 0 0 2px #FFFFFF; }
.photo-large { display: block; width: 100%; height: auto; border-radius: var(--radius-photo); background: var(--tray); }

/* The organiser's box and sheets (the design system's Sheet in a <dialog>) */
.owner { border: 1px solid var(--ballpoint); border-radius: 14px; padding: 14px; display: grid; gap: 12px; box-shadow: var(--shadow-card); }
.owner-label { color: var(--ballpoint); }
.owner .row { flex-wrap: wrap; gap: 16px; }
/* Its own height, on the bottom edge. The height is auto, not the browser's
   fit-content for dialogs: WebKit stretches a fit-content sheet up to its
   max-height instead. */
dialog.sheet { position: fixed; inset: auto 0 0 0; height: auto; margin: 0 auto; width: 100%; max-width: 480px; border: 0; color: var(--ink); }
dialog.sheet::backdrop { background: var(--scrim); }
dialog.sheet:not([open]) { display: none; }
/* Swipe down to close (sheet_controller): the sheet takes vertical drags itself. */
dialog.sheet { touch-action: pan-x; transition: transform .18s cubic-bezier(.16, 1, .3, 1); }
/* In: the sheet slides up as the scrim fades in. Out (sheet_controller adds
   .closing): it slides down from wherever it is as the scrim fades away. */
@media (prefers-reduced-motion: no-preference) {
  dialog.sheet[open] { animation: sheet-up .24s cubic-bezier(.16, 1, .3, 1); }
  dialog.sheet[open]::backdrop { animation: sheet-fade .24s ease-out; }
  dialog.sheet.closing { animation: sheet-down .2s cubic-bezier(.4, 0, 1, 1) forwards; }
  dialog.sheet.closing::backdrop { animation: sheet-fade .2s ease-in reverse forwards; }
  @keyframes sheet-up { from { transform: translateY(100%); } }
  @keyframes sheet-down { to { transform: translateY(100%); } }
  @keyframes sheet-fade { from { opacity: 0; } }
}
@media (prefers-reduced-motion: reduce) { dialog.sheet { transition: none; } }
.sheet-form { display: grid; gap: 12px; margin: 0; }
.stepper { display: flex; align-items: center; justify-content: center; gap: 24px; }
.stepper b { min-width: 7ch; text-align: center; font-size: calc(20rem / 17); font-weight: 600; font-variant-numeric: tabular-nums; }
.clock-note { display: block; color: var(--pencil); font-size: calc(12.5rem / 17); }

/* The replay: full screen on black (as in the prototype) */
.replay { position: fixed; inset: 0; background: #000000; color: #FFFFFF; overflow: hidden; }
.replay-photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.replay-photo:not([src]) { display: none; }
.replay-segs { position: absolute; top: calc(env(safe-area-inset-top, 0px) + 14px); left: 14px; right: 14px; z-index: 2; display: flex; gap: 4px; }
.replay-segs i { flex: 1; height: 3px; border-radius: 2px; background: rgba(255, 255, 255, .35); overflow: hidden; }
.replay-segs b { display: block; height: 100%; background: var(--highlighter); transform: scaleX(0); transform-origin: left; transition: transform .4s linear; }
@media (prefers-reduced-motion: reduce) { .replay-segs b { transition: none; } }
.replay-top { position: absolute; top: calc(env(safe-area-inset-top, 0px) + 28px); left: 16px; right: 16px; z-index: 4; display: flex; justify-content: space-between; font-size: calc(13rem / 17); }
.replay-top a { color: #FFFFFF; text-decoration: none; }
.replay-intro { position: absolute; inset: 0; z-index: 2; display: grid; place-content: center; justify-items: center; gap: 22px; text-align: center; padding: 0 24px; }
/* The name may use the intro's side padding before it wraps, and stops growing at
   15vw with a larger text size */
.replay-title { font-family: var(--font-serif); font-size: min(clamp(calc(40rem / 17), 12vw, calc(64rem / 17)), 15vw); line-height: 1; margin-inline: -24px; }
.replay-meta { font-family: var(--font-mono); font-size: calc(13rem / 17); letter-spacing: .06em; }
.replay-cap { position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; padding: 80px 20px calc(env(safe-area-inset-bottom, 0px) + 34px); background: linear-gradient(to top, rgba(0, 0, 0, .72), transparent); display: grid; gap: 6px; }
.replay-moment { font-family: var(--font-serif); font-size: calc(28rem / 17); line-height: 1.1; }
.replay-by { font-size: calc(15rem / 17); }
.replay-hint { position: absolute; left: 0; right: 0; bottom: 26%; z-index: 2; margin: 0; text-align: center; font-size: calc(15rem / 17); color: rgba(255, 255, 255, .9); pointer-events: none; }
.replay-taps { position: absolute; inset: 80px 0 0; z-index: 3; display: grid; grid-template-columns: 1fr 2fr; }
.replay-taps button { background: none; border: 0; cursor: pointer; }
.replay-taps button:focus-visible { outline: 2px solid var(--highlighter); outline-offset: -4px; }
.now-text { display: grid; gap: 8px; justify-items: start; }

/* The photo page */
.photo-frame { position: relative; }
.photo-frame .landed { position: absolute; width: 52px; height: 52px; filter: drop-shadow(0 2px 3px rgba(11, 37, 48, .25)); }
.landed-0 { right: 10px; bottom: 10px; transform: rotate(-8deg); }
.landed-1 { right: 58px; bottom: 16px; transform: rotate(6deg); }
.landed-2 { right: 104px; bottom: 8px; transform: rotate(-3deg); }
.exif { margin: 0; font-family: var(--font-mono); font-size: calc(11rem / 17); letter-spacing: .1em; color: var(--pencil); }
.sticker-bar { justify-content: space-between; }
.sticker-form { margin: 0; display: contents; }
.notes-list { display: grid; gap: 12px; }
.write { display: grid; grid-template-columns: 1fr auto; gap: 8px; align-items: center; margin: 0; }
.menu-item { display: grid; grid-template-columns: 28px 1fr; gap: 10px; align-items: center; width: 100%; padding: 12px 4px; background: none; border: 0; border-bottom: 1px solid var(--line); color: var(--ink); font: inherit; font-size: calc(16rem / 17); text-align: left; text-decoration: none; cursor: pointer; margin: 0; }
.menu-item small { display: block; color: var(--pencil); font-size: calc(13rem / 17); }
.menu-item.done { cursor: default; color: var(--pencil); }
.owner p { margin: 0; }
.request-line { display: flex; align-items: center; justify-content: space-between; gap: 12px; color: var(--ink); text-decoration: none; }
.request-line .af-link { flex: none; white-space: nowrap; }
.voice-card { display: grid; gap: 12px; }
.hold-to-talk { justify-self: start; touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.landed-stickers { position: absolute; inset: 0; pointer-events: none; }

/* Sharing in an ever after */
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
dialog.sheet:focus { outline: none; }
.end-of-story { display: flex; justify-content: center; gap: 24px; padding-top: 14px; border-top: 1px solid var(--line); } /* apart from the story, under a line */
.danger-link { color: var(--warn); }

/* Previous and next on a photo, and the count */
.photo-frame { touch-action: pan-y; }
.photo-nav { position: absolute; top: 50%; transform: translateY(-50%); z-index: 2; width: 52px; height: 52px; border-radius: 50%; display: grid; place-items: center; background: var(--photo-scrim); color: #FFFFFF; font-size: 28px; line-height: 1; text-decoration: none; }
.photo-nav.prev { left: 10px; }
.photo-nav.next { right: 10px; }
.photo-nav:focus-visible { outline: 2px solid #FFFFFF; outline-offset: 2px; }
.photo-count { position: absolute; top: 12px; right: 12px; z-index: 2; padding: 4px 12px; border-radius: 999px; background: var(--photo-scrim); color: #FFFFFF; font-size: calc(14rem / 17); font-variant-numeric: tabular-nums; }
.photo-voice { display: grid; gap: 10px; }



/* The iPad: a wider page with the 36px gutter (the photo grids and the
   pages that use the whole width are at the end of this file) */
@media (min-width: 700px) {
  .screen { max-width: 760px; padding-left: var(--space-7); padding-right: var(--space-7); }
  .photo-large { max-height: 72vh; object-fit: contain; }
  dialog.sheet { max-width: 560px; }
}

/* A new story with only its organiser: inviting comes first */
.invite-first { display: grid; gap: 8px; padding: 16px; border-radius: 14px; border: 1px solid var(--line); background: var(--panel); box-shadow: var(--shadow-card); }
/* The bottom of Home: Sign out and Delete my account, stacked and centred under a hairline */
.sign-out { margin-top: auto; padding-top: 12px; border-top: 1px solid var(--line); display: flex; flex-direction: column; align-items: center; gap: 4px; }
.sign-out form { margin: 0; }
.sign-out > .sub { padding-bottom: 4px; }
.sign-out .af-link { min-height: 44px; padding: 0 16px; }

/* How long is this story? Each kind drawn, not described: developing tiles
   for a short story, a stack of prints for an ever after. */
.kind-card { gap: 10px; }
.af-story-art .hatch { aspect-ratio: 1; }
.kind-prints { position: relative; display: block; width: 120px; height: 84px; }
.kind-prints i { position: absolute; top: 4px; width: 62px; height: 74px; box-sizing: border-box; background-size: cover; border: 4px solid #FFFFFF; border-bottom-width: 12px; border-radius: 2px; box-shadow: var(--shadow-print); }
.kind-print-1 { left: 2px; transform: rotate(-7deg); background-image: linear-gradient(180deg, #F6B66E, #E77C5A 40%, #6B4A6E 65%, #2C3D55); }
.kind-print-2 { left: 46px; top: 2px !important; transform: rotate(5deg); background-image: radial-gradient(circle at 70% 30%, #FFE2A8 0 12%, transparent 13%), linear-gradient(160deg, #8FC1D4, #3F7B8C 60%, #23454F); }

/* A story's page: the faces under the title open who's in */
.faces-row { display: flex; align-items: center; gap: 10px; padding: 0; border: 0; background: none; font: inherit; color: inherit; text-align: left; cursor: pointer; }
.faces-row .af-face { width: 28px; height: 28px; font-size: 11px; }
.faces-row:focus-visible { outline: 2px solid var(--ballpoint); outline-offset: 4px; border-radius: 8px; }
.icon-btn .af-icon { width: 18px; height: 18px; }
/* Touch targets, as in the design system: the small controls of the app's
   screens take taps on an invisible 44px box centred on them */
:is(.icon-btn, .back, .faces-row, .replay-top a) { position: relative; }
:is(.icon-btn, .back, .faces-row, .replay-top a)::before { content: ""; position: absolute; inset: min(0px, (100% - 44px) / 2); }
/* A story's name in a Swash is the whole title here: it wraps like one rather
   than running off the screen (a long name, a larger text size) */
:is(.page-title, .now-name, .replay-title, .af-credits-title) > .af-swash { white-space: normal; }

.photo-grid .dev-tiles, .photo-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
a.af-dev { text-decoration: none; }

/* The organiser's quiet links, before the reveal */
/* Until the reveal: the faces, then Share the link */
.people-share { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.people-share .faces-row .sub { white-space: nowrap; }
.people-share .af-btn-small { flex: none; white-space: nowrap; }
.face-more { background: var(--tray); color: var(--ink); }
.reveal-line b { color: var(--ink); font-weight: 600; }

/* The organiser's card before the reveal: who's missing, Remind, the reveal time */
.organiser-card { display: grid; gap: 12px; }
.organiser-card .af-label { color: var(--pencil); }
.organiser-card p { margin: 0; }
.organiser-card .sub b { color: var(--ink); font-weight: 600; }
.organiser-waiting { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 10px; }
.organiser-card .faces .af-face { width: 26px; height: 26px; font-size: 11px; border-color: var(--panel); }
.organiser-remind { margin: 0; }
.organiser-remind .af-btn-small { white-space: nowrap; }
.organiser-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
/* Edit the story: the form's fields lay out with the screen's, Reveal now after them in its own form. */
.edit-story { display: contents; }
.organiser-divider { height: 1px; border: 0; margin: 0; background: var(--line); }

/* Moments in an ever after: a name anyone can change, the date under it */
.moment-rename { margin-left: auto; }
.moment-meta { margin-top: -6px; }

/* A new short story: when do photos appear? */
.seg-field { border: 0; margin: 0; padding: 0; display: grid; gap: 8px; }
.seg-field legend { padding: 0; margin-bottom: 8px; }

/* Home: the ever after first, then what's happening now, one compact row each */
.home-section { display: grid; gap: 10px; }
.mini-prints { position: relative; width: 56px; height: 56px; }
.mini-prints img, .mini-prints .hatch { position: absolute; width: 38px; height: 46px; object-fit: cover; box-sizing: border-box; border: 3px solid #FFFFFF; border-bottom-width: 7px; border-radius: 2px; box-shadow: var(--shadow-print); }
.mini-prints > :first-child { left: 2px; top: 4px; transform: rotate(-7deg); }
.mini-prints > :nth-child(2) { left: 16px; top: 2px; transform: rotate(5deg); }

/* A photo: the date, then small sticker pills with their counts */
.photo-meta { display: grid; gap: 10px; }
.af-stickers.sticker-bar { justify-content: flex-start; }
.menu-icon { display: grid; place-items: center; color: var(--ink); }
.menu-icon .af-icon { width: 22px; height: 22px; }

/* A new short story: blank prints, a story with no photos in it yet */
.new-head { display: grid; gap: 10px; padding-bottom: 4px; }
.new-head-prints { max-width: 260px; padding-top: 6px; }
.new-head-prints .af-print-img { background: var(--tray); }


/* Photos on their way up (upload_tiles.js), each in the moment it was taken in.
   Waiting: a tiny thumbnail stretched over the tile (the stretch blurs it, no
   filter to pay for) under faint stripes. Going up: the sharp thumbnail
   uncovered from the bottom as its bytes go up, a bright line at the edge.
   Up: just the photo, with no mark, like every other one. Didn't make it: a
   warn outline (the line at the bottom says how many, with Try again). */
@property --sent { syntax: "<percentage>"; inherits: true; initial-value: 0%; }
.af-tile-going { cursor: default; } /* --sent is eased frame by frame in upload_tiles.js */
.af-tile-going :is(.af-tile-blur, .af-tile-sharp) { position: absolute; inset: 0; background-size: cover; background-position: center; }
.af-tile-going .af-tile-blur { inset: -6%; }
.af-tile-going-soft .af-tile-blur { filter: blur(8px); } /* an older app sends no tiny thumbnail */
.af-tile-going .af-tile-sharp { clip-path: inset(calc(100% - var(--sent)) 0 0 0); }
.af-tile-going .af-tile-edge { position: absolute; left: 0; right: 0; bottom: calc(var(--sent) - 1.5px); height: 3px; background: #FFFFFF; box-shadow: 0 0 0 1px var(--ballpoint), 0 0 8px 1px var(--ballpoint); }
.af-tile-going:is([data-state="waiting"], [data-state="failed"]) :is(.af-tile-sharp, .af-tile-edge),
.af-tile-going:is([data-state="uploaded"], [data-state="landed"], [data-sent]) .af-tile-edge { display: none; }
.af-tile-going[data-state="waiting"]::after { content: ""; position: absolute; inset: 0; background: repeating-linear-gradient(-45deg, transparent 0 6px, #FFFFFF26 6px 12px); }
.af-tile-going[data-state="failed"] { outline: 2px solid var(--warn); outline-offset: -2px; }
.af-tile-going[data-state="failed"] .af-tile-blur { opacity: .5; }
.moment-coming-count { font-size: calc(12.5rem / 17); color: var(--pencil); white-space: nowrap; }
.moment-coming .moment-head h2 { color: var(--pencil); }
.af-tile[data-photo-id] { background-size: cover; background-position: center; }

/* The app's system navigation bar (iOS or Android) carries back and the page's action
   (native_navigation?): the page's own bar steps aside. A story keeps its big
   title, highlighter or Swash included, and the bar shows the name only once
   it has scrolled away; modals keep their title in the bar. */
.native-navigation :is(.bar, .front-bar, .page-title, .sign-in-wordmark, .join-wordmark) { display: none; }
.native-navigation .story-page .page-title { display: block; }
/* The app runs a story page up under its see-through bar (title_under_bar?):
   the title's first line sits level with back and starts just past it. The
   app measures both (bridge/page_title_controller.js), starting from the
   platform's usual bar (title_under_bar_style). */
.title-under-bar { padding-top: 0; }
.title-under-bar .page-title { padding-top: max(0px, calc(var(--bar-height) / 2 - .5lh)); text-indent: var(--title-indent); }
.native-status { display: flex; }

/* Nothing that says "web page" in the app: no grey flash on a tap, no
   link preview or "Save image" on a long press, no text selection on things
   to tap. What people wrote stays selectable. */
.native-navigation { -webkit-tap-highlight-color: transparent; }
.native-navigation :is(img, a, .af-tile) { -webkit-touch-callout: none; -webkit-user-drag: none; }
.native-navigation :is(a, button, label, .af-tile, .af-pill, .af-label, .moment-head) { -webkit-user-select: none; user-select: none; }

/* A story the reveal job is about to open: the line under the title says so */
.revealing-line b { color: var(--ink); font-weight: 600; }

/* Right after joining: "You're in", and the way to add photos */
.welcome-card { gap: 10px; padding: 16px; }
.welcome-card p { margin: 0; }
.welcome-card b { font-weight: 600; }
.welcome-title { margin: 0; font-family: var(--font-serif); font-weight: 400; font-size: calc(20rem / 17); line-height: calc(26rem / 17); }
.welcome-note { text-align: center; }

/* The credits: the group's favourites as prints, each with its sticker count */
.favourites { display: grid; gap: 10px; }
.favourite-prints { width: 100%; max-width: 280px; justify-self: center; justify-content: center; box-sizing: border-box; }
.favourite-prints .af-print { text-decoration: none; margin-left: -3%; } /* less overlap than a stack: each stamp stays readable */
.favourite-prints .af-print:first-child { margin-left: 0; }
.favourite-prints .af-print-img { width: 100%; height: auto; object-fit: cover; }
.voice-card [data-voice-record-target=status]:empty { display: none; } /* no gap under the button until it has something to say */
.voice-card-title { margin: 0; font-size: calc(15rem / 17); line-height: calc(22rem / 17); font-weight: 600; }
.voice-card .hold-to-talk.af-btn-block { justify-self: stretch; }
.hold-to-talk-cancel { justify-self: center; min-height: 44px; padding: 0 16px; }
.foot-link { display: flex; justify-content: center; }
.foot-link .af-link { min-height: 44px; padding: 0 16px; }
/* After the reveal: the replay card, then one short list (voice notes, download) */
.replay-card { display: grid; grid-template-columns: 112px 1fr; align-items: center; gap: 14px; padding: 8px 14px 8px 8px; background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-card); box-shadow: var(--shadow-card); color: var(--ink); text-decoration: none; }
.replay-card-cover { position: relative; display: grid; place-items: center; aspect-ratio: 4 / 3; border-radius: 9px; overflow: hidden; background: var(--tray); }
.replay-card-cover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.replay-card-cover .af-play { position: relative; width: 40px; height: 40px; font-size: 14px; box-shadow: 0 0 0 3px rgba(255, 255, 255, .85); }
.replay-card-text { display: grid; gap: 4px; }
.replay-card-text b { font-family: var(--font-serif); font-weight: 400; font-size: calc(20rem / 17); line-height: 1.2; }
.replay-card-meta { font: 500 calc(11rem / 17)/1.4 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--pencil); }
.replay-card:focus-visible, .story-row:focus-visible { outline: 2px solid var(--ballpoint); outline-offset: 2px; }
.story-rows { list-style: none; margin: 0; padding: 0; background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-card); }
.story-rows li + li { border-top: 1px solid var(--line); }
.story-row-form { margin: 0; }
.story-row { display: grid; grid-template-columns: 34px 1fr auto; align-items: center; gap: 12px; width: 100%; min-height: 60px; padding: 10px 14px; border: 0; background: none; font: inherit; color: var(--ink); text-align: left; text-decoration: none; cursor: pointer; }
.story-row:disabled { cursor: default; }
.story-row-text { display: grid; gap: 1px; }
.story-row-text b { font-weight: 600; font-size: calc(15rem / 17); }
.story-row-icon { width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; background: var(--tray); color: var(--ballpoint); }
.story-row-icon .af-icon { width: 18px; height: 18px; }
.story-row-voice { background: var(--ballpoint); color: var(--on-ballpoint); font-size: 12px; }
.story-row-chev { color: var(--pencil); font-size: 20px; }
/* The group's favourites: each with its most used sticker and that sticker's count */
.favourite-badge { position: absolute; left: 6px; bottom: 6px; display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px 2px 4px; border-radius: var(--radius-pill); background: var(--panel); box-shadow: var(--shadow-card); color: var(--ink); }
.favourite-badge img { position: static; width: 22px; height: 22px; }
.favourite-badge b { font-size: calc(12rem / 17); font-weight: 600; font-variant-numeric: tabular-nums; }
/* A reveal with no photos */
.empty-reveal { display: grid; gap: 10px; }
.empty-reveal p { margin: 0; }

/* The app's replies sheet: whose photo, the stickers full size, the notes,
   then the note field at the bottom */
.replies-title { margin: 0; font-family: var(--font-serif); font-weight: 400; font-size: calc(20rem / 17); line-height: calc(26rem / 17); }
.sticker-row { justify-content: space-between; }
.sticker-row .af-sticker-art { width: 40px; height: 40px; }
.replies-page .notes-list { flex: 1; display: flex; flex-direction: column; padding-top: 12px; border-top: 1px solid var(--line); }
.replies-page .notes-list .write { margin-top: auto; }
.replies-page .write .af-btn { min-height: 50px; } /* as tall as the field beside it */

/* Report and block: the small "more" after someone else's note, voice note or
   row in Who's in, the sheet about a person, and the report's reasons page. */
.mini-more { position: relative; width: 30px; height: 30px; display: grid; place-items: center; padding: 0; border: 0; border-radius: 50%; background: none; color: var(--pencil); cursor: pointer; flex: none; }
.mini-more::before { content: ""; position: absolute; inset: -7px; } /* a 44px target */
.mini-more .af-icon { width: 18px; height: 18px; }
.mini-more:focus-visible { outline: 2px solid var(--ballpoint); outline-offset: 2px; }
.more-about { margin: 0; }
.af-note .byline { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.af-voice.has-more { grid-template-columns: 34px 1fr auto auto; }
.people-list li .more-about { margin-left: auto; }
.sheet-person { display: flex; align-items: center; gap: 10px; }
.menu-item .menu-icon:empty { min-height: 22px; }
.report-head { display: grid; gap: 6px; }
.report-reasons { display: grid; gap: 6px; margin: 0; padding: 0; border: 0; min-width: 0; }
.report-reasons .af-choice-opt { padding: 11px 14px; }
.report-reasons .af-choice-opt:has(input:checked) { padding: 10px 13px; }
.report-reasons b { font-weight: 500; }
.report-form:not(:has(.report-reasons input:checked)) .report-details { display: none; }
.moderation-facts { display: grid; grid-template-columns: auto 1fr; gap: 6px 14px; margin: 0; }
.moderation-facts dt { color: var(--pencil); }
.moderation-facts dd { margin: 0; }
.moderation-actions { display: grid; gap: 10px; }

/* The replay and its short list: spaced like the rest of the page on a
   phone, side by side on a tablet (below) */
.story-lead { display: grid; gap: var(--space-4); }

/* Tablets (iPads, Android 10" in portrait and up): the pages people look at
   use the width; forms, sign-in and sheets keep their reading width.
   Last in the file so the grids win over the 3 columns above. */
@media (min-width: 760px) {
  :is(.story-page, .home-page, .photo-page:not(.replies-page)) { max-width: 1120px; }
  .story-page :is(.photo-grid, .dev-tiles) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  /* The replay beside the voice notes and the download */
  .story-lead { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; }
  .story-lead > * { margin: 0; }
  .story-lead > :not(.replay-card, .story-rows) { grid-column: 1 / -1; }
  /* Home: the sections side by side, two a row */
  .home-page { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: var(--space-6); align-content: start; }
  .home-page > :not(.home-section, .list) { grid-column: 1 / -1; }
  .home-page > .sign-out { align-self: end; }
}
@media (min-width: 1000px) {
  .story-page :is(.photo-grid, .dev-tiles) { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}
/* A photo on the web, on a tablet held sideways: the photo large, what
   people said beside it */
@media (min-width: 1000px) and (orientation: landscape) {
  .photo-page:not(.replies-page) { display: grid; grid-template-columns: minmax(0, 2fr) minmax(320px, 1fr); column-gap: var(--space-6); align-content: start; }
  .photo-page:not(.replies-page) > * { grid-column: 2; }
  .photo-page:not(.replies-page) > :is(.bar, .flash, .toast, #removal-request) { grid-column: 1 / -1; }
  .photo-page:not(.replies-page) > .photo-frame { grid-column: 1; grid-row: span 6; align-self: start; }
  .photo-page:not(.replies-page) .photo-large { max-height: calc(100dvh - 140px); }
}
