/* Journal — app styles on top of modernist.css. Variant A · Scrapbook only.
   Values follow design/Journal App.dc.html and design/README.md exactly. */

/* App-specific tokens. Photo frames, chips and quotes sit on paper-white in *both* themes, so
   their ink cannot follow --color-text: on dark that would render light on light. */
:root{--jr-photo:#fff;--jr-photo-ink:#201e1d;--jr-photo-mute:#6f6b6b}

/* ─── the softer palette ──────────────────────────────────────────────────────
   Layered surfaces instead of rules, filled controls instead of outlined ones, 14px corners. The
   dark set is the design's, value for value. The light set was never drawn: it is the same shapes
   inverted sensibly — bars and sheets a step lighter than the page, every control and card a step
   darker — with every text colour at 4.5:1 or better on what it sits on. That is why the light
   primary fill is #d42a10 and not the accent: white on #ec3013 is 4.20:1.
   The old names are pointed at the new ones rather than replaced, so every screen nobody has
   restyled yet already wears the new colours. modernist.css keeps its own values underneath. */
:root{--page:#f3f2f2;--surface-1:#e7e4e2;--surface-2:#dad6d3;--surface-3:#cdc8c5;--bar:#faf9f9;--tabbar:#fbfafa;
  --rule-head:#d6d1ce;--rule-tab:#ddd8d5;--rule:#d9d4d1;
  --text:#201e1d;--text-2:#46423f;--muted:#615c59;--placeholder:#67625f;--disabled:#696461;--empty:#696461;
  --accent:#ec3013;--accent-fill:#d42a10;--on-accent:#fff;--accent-text:#b02008;--bubble-own:#c42a12;
  --accent-tint:#fbe1d9;--accent-tint-text:#b02008;--accent-soft:#b8301a;--hand:#cc3419;
  --sel-bg:#201e1d;--sel-fg:#f3f2f2;--grab:#b3aeab;--sheet-shadow:0 -8px 30px rgba(32,30,29,.18);--av-pale-ink:#f3f2f2;
  --radius-sm:8px;--radius-md:14px;--radius-lg:24px;
  --color-bg:var(--page);--color-surface:var(--surface-1);--color-text:var(--text);--color-divider:var(--rule);
  --color-neutral-100:var(--surface-1);--color-neutral-300:var(--surface-3);
  --color-neutral-600:var(--muted);--color-neutral-700:var(--text-2);
  --color-accent-100:var(--accent-tint);--color-accent-800:var(--accent-soft)}

/* ─── dark theme overrides ──────────────────────────────────────────────── */
.jr-dark{--jr-photo:#f3f2f2;
  --page:#1f1d1c;--surface-1:#2c2928;--surface-2:#3a3634;--surface-3:#45403e;--bar:#252322;--tabbar:#232120;
  --rule-head:#3b3735;--rule-tab:#34302f;--rule:#3f3a38;
  --text:#f1eeec;--text-2:#cdc8c5;--muted:#a39e9b;--placeholder:#8f8a87;--disabled:#7d7876;--empty:#6f6a68;
  --accent-fill:#ec3013;--accent-text:#f07a63;
  --accent-tint:#3a1a14;--accent-tint-text:#ff6a4f;--accent-soft:#f07a63;--hand:#f0563b;
  --sel-bg:#f1eeec;--sel-fg:#1f1d1c;--grab:#5b5654;--sheet-shadow:0 -8px 30px rgba(0,0,0,.45);--av-pale-ink:#1f1d1c;
  --color-neutral-400:#7d7979;--color-neutral-800:#eae7e7;
  --shadow-sm:0 1px 2px rgba(0,0,0,.5);--shadow-md:0 3px 10px rgba(0,0,0,.55)}


/* ─── native-app shell ──────────────────────────────────────────────────── */
html,body{height:100%;margin:0;overscroll-behavior:none;touch-action:manipulation;-webkit-text-size-adjust:100%;text-size-adjust:100%}
/* On a phone the body is the app's own colour, not the desk grey: while the keyboard animates, the
   shell can trail the visual viewport by a frame, and the sliver of body that shows in that frame
   must be the same colour as the screen or it reads as a flicker. The grey is a desktop thing. */
body{background:var(--color-bg);font-family:var(--font-body);overflow:hidden;position:fixed;inset:0}
/* Top is nought and stays nought: see native.js on why the visual viewport's offset is not
   followed. The height is the whole of what the keyboard is allowed to change. */
#desk{position:fixed;left:0;right:0;top:0;height:var(--vvh,100dvh);display:flex;justify-content:center;align-items:flex-start;overflow:hidden}
.shell{width:100%;height:100%;background:var(--color-bg);color:var(--color-text);display:flex;flex-direction:column;position:relative;overflow:hidden;font-family:var(--font-body);font-size:15px;line-height:1.5}
/* The desk framing is for a *desktop*, not for a big phone. 421px caught a 14/15 Pro Max, which
   letterboxed the app to 390px — and, worse, replaced the visual-viewport height with 100dvh, so
   the keyboard pinning below stopped working on exactly those phones. 600px clears every phone in
   portrait and still catches tablets. Height and top keep following the visual viewport at every
   width, so the keyboard never covers what you are typing, landscape included. */
@media (min-width:600px){
  body{background:#cfcaca}
  #desk{padding:28px 0}
  .shell{max-width:390px;max-height:844px;box-shadow:var(--shadow-lg)}
}
/* ─── a phone that has been asked for less movement ─────────────────────────
   The six rules further down this file already answer the preference one at a time: the tile, the
   beat, the letter's seal, the question switch. They were written as each of those was built, so
   what they cover is what somebody happened to be looking at — and there are animations in here
   running as long as 2.4 seconds that nobody thought about. This is the floor under all of them.
   The setting is not a preference about taste: for some people motion on a screen is nausea, and
   for some it is a migraine.
   Not removed, reduced to a frame. A duration of zero cancels an animation outright and anything
   waiting to hear it finish never does; a hair over one frame ends before it can be felt and still
   fires. Nothing in this app listens for transitionend today, but a stylesheet outlives the
   JavaScript it was written next to. Smooth scrolling goes with it — a page that glides is the
   same complaint at a larger size. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
  html, body, .scroll { scroll-behavior: auto !important; }
}

.scroll{overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;touch-action:pan-y;scrollbar-width:none;min-height:0}
.scroll::-webkit-scrollbar{display:none}
.hscroll{overflow-x:auto;overflow-y:hidden;touch-action:pan-x;scrollbar-width:none;overscroll-behavior-x:contain}
.hscroll::-webkit-scrollbar{display:none}
.chrome,.tile,.tabbar,button,.sheet-tabs,[role=button]{user-select:none;-webkit-user-select:none;-webkit-touch-callout:none}
.tile img,.tile video,.cover img,[role=button] img{-webkit-user-drag:none;user-drag:none;pointer-events:none}
img{display:block}
button{font-family:inherit;touch-action:manipulation}
input,textarea,select{font-size:16px !important;touch-action:manipulation}
.input{font-size:16px}
/* Fields are filled, with no edge at rest — the edge is kept, transparent, so nothing changes size —
   and focus is the app's ring, 2px of accent two pixels out, not a red border. */
.input{background-color:var(--surface-1);border-color:transparent}
.input:hover{border-color:transparent}
.input:focus-visible{border-color:transparent;outline:2px solid var(--color-accent);outline-offset:2px}
.input::placeholder{color:var(--placeholder);opacity:1}
textarea.input{resize:none}
select.input{-webkit-appearance:none;appearance:none;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23201e1d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>");background-repeat:no-repeat;background-position:right 10px center;background-size:16px;padding-right:32px}
.jr-dark select.input{background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23f1eeec' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>")}
/* Flat since the softer restyle: the design layers plain surfaces, and the scrapbook's paper grain was
   the one texture left in the app — on the forms and the invitation page. The class stays: tests and
   the post's layout read it. */
.paper{background-image:none}
/* Accent as *text* is --accent-text, which reads at 4.5:1 or better on the page in both themes; the
   accent itself is for fills and marks, and as small text it measures 3.76:1 light and 4.00:1 dark. */
a{color:var(--accent-text)}a:hover{color:var(--color-accent-600)}
.hw{font-family:'Reenie Beanie',cursive}
.safe-top{padding-top:env(safe-area-inset-top)}
@keyframes jrToast{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@keyframes jrSheet{from{transform:translateY(100%)}to{transform:none}}
@keyframes jrPulse{0%,100%{opacity:1}50%{opacity:.45}}

/* ─── shared bits ───────────────────────────────────────────────────────── */
.screen{flex:1;display:flex;flex-direction:column;min-height:0}
/* The journal, which is the one screen that is not taken down to open something on it. It is the
   screen when you are on it, and a hidden layer underneath when you are reading a post — same
   element either way, so nothing is rebuilt between the two. See App.
   `visibility:hidden` and not `display:none`: a box with no layout has no scroll position, and the
   scroll position is the whole point. It is out of the flex flow while it is away so that the post
   on top gets the height, and it takes no pointer events so nothing on it can be hit through. */
.jkeep{flex:1;display:flex;flex-direction:column;min-height:0}
/* `content-visibility` and not `visibility`, which is faster and was measured and rejected.
   Hidden with `visibility` the spread comes back in about 40ms against this one's 360, because its
   layout is never dropped — but something above the window then loses a couple of hundred pixels
   across the trip, the browser anchors the scroll to compensate, and `small3` sees a position that
   has moved. The view is right and the number is not, and shipping a number I cannot account for on
   the strength of it being quick is how the rail got to five rounds. This one is honest and green. */
.jkeep.away{position:absolute;left:0;right:0;top:0;bottom:0;flex:none}
.jkeep.away{pointer-events:none;visibility:hidden}
/* Under the Add sheet rather than behind a post: still there, still readable, and not a surface
   anybody can touch through. It is what makes Add feel like something raised over what you were
   doing instead of somewhere you went. */
.jkeep.under{position:absolute;left:0;right:0;top:0;bottom:0;flex:none;pointer-events:none;opacity:.28}
/* Under the comment popup the spread keeps its own colours — the wash is the popup's, drawn over
   everything at once (see .cwash), not something the spread does to itself. What it must not do is
   move: a feed that scrolls behind a popup slides the post out from under its own comments. */
.jkeep.nopull .desk{touch-action:none;overflow:hidden}
.h1{font-family:var(--font-heading);font-weight:800;font-size:28px;line-height:1;letter-spacing:-.03em;margin:0}
.kicker{font-size:11px;letter-spacing:.1em;text-transform:uppercase;font-weight:400;margin:0}
.muted{color:var(--color-neutral-600)}
/* A browse screen's header has no rule under it: space and the surfaces below do the separating.
   A composer's header keeps its 2px rule (.cshell .chead), and so does the plain .bar for now —
   it heads forms as often as it heads lists, and each of those screens is restyled on its own. */
.hdr{padding:20px 16px 8px;display:flex;align-items:flex-end;justify-content:space-between}
.bar{display:flex;align-items:center;gap:4px;padding:10px 12px 8px 8px;border-bottom:2px solid var(--rule-head)}
/* ── buttons ──────────────────────────────────────────────────────────────────────────────────
   Filled, never outlined. One red primary; secondary on the surface with no edge; ghost is text in
   the accent's text colour. Disabled is a surface with quiet ink rather than the system's 45%
   opacity, which on a filled button takes the label down with it. These come before .icon-btn and
   everything else in this file on purpose: a screen's own rule for one of these still wins. */
.btn-primary,.btn-secondary,.btn-ghost{min-height:40px}
/* White on the fill in both themes. modernist.css inks it with --color-bg, which on dark is near-black;
   the dark-only override that used to correct that is gone, because it also beat :disabled below. */
.btn-primary{background:var(--accent-fill);color:var(--on-accent);border-color:transparent}
.btn-primary:hover{background:color-mix(in srgb,var(--accent-fill) 90%,#000)}
.btn-primary:active{background:color-mix(in srgb,var(--accent-fill) 80%,#000)}
.btn-secondary{background:var(--surface-1);color:var(--color-text);border-color:transparent}
.btn-secondary:hover{background:var(--surface-2)}
.btn-secondary:active{background:var(--surface-3)}
.btn-ghost{color:var(--accent-text)}
.btn-primary:disabled,.btn-secondary:disabled{opacity:1;background:var(--surface-1);color:var(--disabled)}
.btn-ghost:disabled{opacity:1;color:var(--disabled)}
/* The round icon button. Bare by default, so the arrow in a composer's header is still just an
   arrow; a circle all the same, so what lights under a finger is round. Where the design draws a
   disc — the back on a journal and on a post — it is 38px, drawn inside the 44px it has always
   been to hit. The big feed's back is not drawn in the design; it takes the journal's disc, its
   header being the journal's shape, rather than the browser's own 2px outset edge. */
.icon-btn{width:44px;height:44px;padding:0;color:var(--color-text);flex:none;border-radius:50%}
.btn.btn-icon{border-radius:50%}
.btn-secondary.btn-icon,.btn-primary.btn-icon{width:40px;height:40px}
.jhead .row1>.icon-btn:first-child,.screen.detail>.bar>.icon-btn:first-child,.fdhead>.back.icon-btn{border:0;padding:3px;
  background-color:var(--surface-1);background-clip:content-box}
.btn.h44{min-height:44px}.btn.h48{min-height:48px;margin:0}.btn.h36{min-height:36px}
.btn-block{margin:0}
.avatar{display:grid;place-items:center;flex:none;color:#f3f2f2;font-family:var(--font-heading);font-weight:800;line-height:1;overflow:hidden;position:relative;border-radius:50%}
.avatar img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.avatar .avmark{position:absolute;inset:0;width:100%;height:100%;display:block}
.avmark{display:block;width:100%;height:100%}
.avmark.fill{position:absolute;inset:0}
.av14{width:14px;height:14px;font-size:8px}.av16{width:16px;height:16px;font-size:8px}.av18{width:18px;height:18px;font-size:9px}
.av22{width:22px;height:22px;font-size:10px}.av20{width:20px;height:20px;font-size:9px}.av24{width:24px;height:24px;font-size:11px}.av26{width:26px;height:26px;font-size:12px}.av32{width:32px;height:32px;font-size:14px}.av36{width:36px;height:36px;font-size:16px}.av40{width:40px;height:40px;font-size:17px}.av44{width:44px;height:44px;font-size:18px}.av56{width:56px;height:56px;font-size:26px}.av64{width:64px;height:64px;font-size:30px}
.avrow{display:flex;gap:2px}
.strip{display:inline-block;background:var(--color-text);color:var(--color-bg);font-family:var(--font-heading);font-weight:600;font-size:11px;letter-spacing:.1em;text-transform:uppercase;padding:7px 10px;line-height:1.35;box-shadow:var(--shadow-sm);max-width:100%;overflow-wrap:anywhere}
.tape{position:absolute;top:-9px;left:50%;height:18px;background:rgba(255,255,255,.55);border:1px solid rgba(0,0,0,.07);box-shadow:0 1px 1px rgba(0,0,0,.08);z-index:2;pointer-events:none}
/* Emotion and place: rectangular chips, not stamps. They sit on paper-white in both themes, so
   their fill and ink come from the --jr-photo* tokens and never from --color-text. */
.stamp{display:inline-flex;align-items:baseline;gap:8px;border:2px solid var(--jr-photo-ink);background:var(--jr-photo);color:var(--jr-photo-ink);padding:5px 10px;font-family:var(--font-heading);font-weight:800;line-height:1;white-space:nowrap;flex:none}
.stamp .lbl{font-size:9px;letter-spacing:.14em;text-transform:uppercase;font-weight:600}
.stamp .num{font-size:15px;letter-spacing:-.02em;color:var(--color-accent-700)}
.stamp .of{font-size:9px;color:var(--jr-photo-mute);font-weight:600}
.stamp.big{padding:8px 12px}
.stamp.big .num{font-size:24px;letter-spacing:-.03em}
.chip{min-height:40px;padding:0 13px;border:0;border-radius:var(--radius-md);background:var(--surface-1);color:var(--text-2);font:inherit;font-size:13px;font-weight:800;cursor:pointer;display:inline-flex;align-items:center;gap:8px}
.chip.on{background:var(--sel-bg);color:var(--sel-fg)}
.chip.accent.on{background:var(--accent-fill);color:var(--on-accent)}
.chip.w400{font-weight:400}
.chip.av{padding-left:6px}
.chiprow{display:flex;gap:6px;flex-wrap:wrap}
.lock{position:absolute;top:8px;right:8px;width:22px;height:22px;background:var(--color-bg);display:grid;place-items:center;pointer-events:none;color:var(--color-text)}
.media-box{position:relative;background:var(--color-surface);overflow:hidden}
.media-box img,.media-box video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.media-box .ph{position:absolute;inset:0;display:grid;place-items:center;color:var(--color-neutral-600);font-size:11px;text-align:center;padding:8px;line-height:1.3;text-transform:uppercase;letter-spacing:.06em}
.empty{padding:40px 20px;font-size:14px;color:var(--color-neutral-600)}
.hint{padding:16px;font-size:12px;color:var(--color-neutral-600)}
.busy{animation:jrPulse 1s ease-in-out infinite}
/* Clipped, not hidden: iOS will not open a picker for an input that is zero-sized or has
   pointer-events:none, so it keeps a real box and is cut out of view instead. */
.file-input{position:absolute;left:0;top:0;width:1px;height:1px;opacity:0;overflow:hidden;clip-path:inset(50%)}

/* ─── tab bar ───────────────────────────────────────────────────────────── */
/* A pulled list is moved with a transform, which lifts it into the positioned layer. The bars that
   sit below a list have to be raised too, or the content slides over them instead of under them. */
.tabbar,.detail .composer,.join-preview .foot,.landing .foot{position:relative;z-index:1}
/* Five cells, so Add is the middle one — and every column a fixed share of the width, never 1fr,
   because a plain 1fr keeps each column at least as wide as its own content: "Journals" is the
   longest label and was widening its cell at the expense of the other four, which moved Add off
   centre. Each cell is a column, icon over label, centred; the one you are on is a tinted pill
   rather than a red word, and nothing divides the pills but 4px of bar.
   The buttons fill the bar edge to edge and the pill is drawn inside each one: a bar with its own
   padding and gaps is a bar with strips that are not a button, and a thumb landing on the top edge
   of it went nowhere. So each column carries the bar's 10px side or half of a 4px gap as padding,
   and the pills land exactly where a padded bar would put them. Only the safe area is the bar's.
   Not clipped: at 360px "HINZUFÜGEN" is 68px over a 65px pill, and cutting the H off it is worse
   than letting it run a pixel and a half past the pill either side. Below 360 the pill is 57 and it
   ran 7px past, into its neighbours' pills, so there a long language's labels lose their tracking. */
.tabbar{display:grid;gap:0;padding:0 0 env(safe-area-inset-bottom);
  grid-template-columns:calc((100% - 36px) / 5 + 12px) repeat(3,calc((100% - 36px) / 5 + 4px)) calc((100% - 36px) / 5 + 12px);
  border-top:2px solid var(--rule-tab);background:var(--tabbar);flex:none}
.tabbar button{position:relative;isolation:isolate;padding:16px 2px 20px;overflow:visible;white-space:nowrap;border:0;border-radius:0;background:transparent;
  color:var(--text-2);font:inherit;cursor:pointer;display:flex;flex-direction:column;align-items:center;gap:5px;
  font-size:9px;line-height:10px;letter-spacing:.08em;text-transform:uppercase;font-weight:800}
.tabbar button::before{content:'';position:absolute;top:8px;bottom:12px;left:2px;right:2px;border-radius:14px;z-index:-1}
.tabbar button:first-child{padding-left:10px}
.tabbar button:last-child{padding-right:10px}
.tabbar button:first-child::before{left:10px}
.tabbar button:last-child::before{right:10px}
.tabbar button.on{color:var(--accent-tint-text)}
.tabbar button.on::before{background:var(--accent-tint)}
.tabbar button:focus-visible{outline:0}
.tabbar button:focus-visible::before{outline:2px solid var(--color-accent);outline-offset:2px}
.tabbar svg{display:block;width:18px;height:18px;stroke-width:2}
/* The unread mark hangs off the icon, not off the cell: a longer label in another language must not
   move it. Round now, with a ring of whatever it sits on so it never touches the glyph's stroke. */
.tabbar .ico{position:relative;display:block;line-height:0}
.tabbar .ico .dot{position:absolute;top:-2px;right:-3px;width:8px;height:8px;border-radius:50%;background:var(--color-accent);
  box-shadow:0 0 0 2px var(--tabbar);display:block}
.tabbar button.on .ico .dot{box-shadow:0 0 0 2px var(--accent-tint)}
.kb .tabbar{display:none}
@media (max-width:359px){:root:not(:lang(en)) .tabbar button{letter-spacing:0}}

/* ─── toast ─────────────────────────────────────────────────────────────── */
/* Notifications on this device. */
/* Framing a photo before it is posted: the frame is the photo's own shape, zoom pushes in. */
/* Tall photos would otherwise push the caption and the zoom off the screen, so the frame is
   capped by height and keeps its shape by shrinking in width. */
.framebox{position:relative;background:var(--color-surface);overflow:hidden;margin:0 auto;width:100%}
.photoframe{position:absolute;inset:0;overflow:hidden;touch-action:pan-y}
/* The frame takes the gesture whenever there is something to do with it — pushed in, where the
   drag pans, and on any picture that is not square, where at rest it places the square. Both are
   the same rule: on this screen a drag on the photograph is framing it, so `pan-y` would hand the
   vertical half of that to the page and the square would only ever move sideways. */
.photoframe.zoomed,.photoframe.framing{cursor:grab;touch-action:none}
.photoframe.zoomed:active{cursor:grabbing}
.photoframe img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;transform-origin:center;user-select:none;-webkit-user-drag:none}
/* The library, under the frame: the camera is the phone's own now, so there is no button inside
   it that reaches the photos. Secondary and full width, so the frame stays the loud one. */
/* The column it is in already has a gap; the margin was a second one under the first. */
/* On a shot just taken: keep it on the phone, since the camera button never put it there. Bottom
   left of the picture, opposite Change, so the editor gives up no height for it. */
.keepbtn{position:absolute;left:8px;bottom:8px;z-index:3;background:var(--color-bg);gap:5px}
/* Stickers: cut-outs, so they sit straight on the page with a small lift, no frame around them. */
.sticker{display:block;width:100%;aspect-ratio:1;object-fit:contain;filter:drop-shadow(0 2px 3px rgba(45,43,43,.28));user-select:none}
.sticker.gone{border:1.5px dashed var(--color-divider);filter:none}
.hero-sticker{display:grid;place-items:center;margin:4px 14px 0;padding:30px 16px 22px;border-radius:var(--radius-md);background:var(--surface-1)}
.hero-sticker .sticker{width:176px}
.th-sticker{display:grid;place-items:center;padding:8%}
/* What's new: the bell, the marks on covers and tiles, the list, and the banner. */
.bellbtn{position:relative;padding:0 10px}
/* Counts are round now, ringed in the page so they lift off whatever they overlap. */
.bellbtn .count{position:absolute;top:-6px;right:-6px;min-width:16px;height:16px;padding:0 4px;border-radius:8px;box-shadow:0 0 0 2px var(--page);background:var(--accent-fill);color:#fff;font-family:var(--font-heading);font-weight:800;font-size:9px;display:grid;place-items:center;line-height:1}
.cover .newmark{position:absolute;top:8px;left:8px;min-width:20px;height:20px;padding:0 6px;border-radius:10px;background:var(--accent-fill);color:#fff;font-family:var(--font-heading);font-weight:800;font-size:10px;display:grid;place-items:center;line-height:1;z-index:2}
/* ── Unread is on the tile ──────────────────────────────────────────────────────────────────

   The spread is a mosaic now and has no margin to draw a rail in, so what is unread is drawn round
   the post itself: a 2px ring of accent for news, and a hairline of it for a like, which takes
   itself away a moment after the journal is on screen. A shadow rather than a border or an
   outline with an offset, so the tile's box never changes and nothing shifts by a pixel when a mark
   lands or clears; and it fades on the shadow, never on opacity — the walk below dims everything it
   is not about by setting opacity directly, and a transition there would stick at its start. The
   card of a stack of scales lights the same way. The guided bar and the dimming are unchanged:
   they are about where to go next, which is a different question from what is unread here. */
.tile,.scard{position:relative;transition:box-shadow .45s ease}
.tile.news,.scard.news{box-shadow:0 0 0 2px var(--color-accent)}
.tile.news.seen{box-shadow:0 0 0 2px transparent}
.tile.isnew.soft{box-shadow:0 0 0 1px color-mix(in srgb,var(--color-accent) 55%,transparent)}
.tile.isnew.soft.seen{box-shadow:0 0 0 1px transparent}
@media (prefers-reduced-motion:reduce){.tile,.scard{transition:none}}
/* ── The bar: where the next one is ───────────────────────────────────────────────────────────

   Under the tab strip and above the feed, never sticky inside it. A card of its own, a step up from
   the page, so it reads as a control rather than as another post: how many are left in an accent
   disc, where it will take you, and which way. The whole bar is the button. The count is 20/800,
   which is large text, so white on the accent fill clears 3:1 in both themes (4.9 and 4.2). */
.unbar{flex:none;display:flex;align-items:center;gap:12px;min-height:56px;width:auto;margin:0 14px 8px;padding:8px;border:0;
  border-radius:var(--radius-md);background:var(--surface-1);color:var(--text);font:inherit;text-align:left;cursor:pointer}
.unbar .n{flex:none;width:40px;height:40px;border-radius:50%;background:var(--accent-fill);color:var(--on-accent);
  display:grid;place-items:center;font-family:var(--font-heading);font-weight:800;font-size:20px;
  line-height:1;font-variant-numeric:tabular-nums}
.unbar .txt{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px;padding:0}
.unbar .k{font-family:var(--font-heading);font-weight:800;font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--accent-text)}
.unbar .w{font-family:var(--font-heading);font-weight:800;font-size:14px;letter-spacing:-.01em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-variant-numeric:tabular-nums}
.unbar .go{flex:none;width:40px;height:40px;border-radius:50%;background:var(--surface-2);display:grid;place-items:center}
/* Nothing left to be sent to: a round button over the spread, bottom right, and all it does is put
   you back at the top. It floats, so it takes no line of the screen and nothing moves as it comes
   or goes. Drawn 40 inside the 44 it is hit at — the disc and its shadow are the ::before. Above
   the dots (4), under the Add sheet and the popup (30 and up). A kept journal hides it. */
.totop{position:absolute;right:14px;bottom:14px;z-index:5;width:44px;height:44px;padding:0;border:0;border-radius:50%;
  background:transparent;color:var(--text);display:grid;place-items:center;isolation:isolate;cursor:pointer;
  -webkit-tap-highlight-color:transparent}
.totop::before{content:'';position:absolute;inset:2px;border-radius:50%;background:var(--bar);z-index:-1;
  box-shadow:0 4px 14px rgba(0,0,0,.22),0 0 0 1px var(--rule)}
.jr-dark .totop::before{box-shadow:0 4px 14px rgba(0,0,0,.5),0 0 0 1px var(--rule)}
.totop:focus-visible{outline:0}
.totop:focus-visible::before{outline:2px solid var(--color-accent);outline-offset:2px}
.jkeep.away .totop,.jkeep.under .totop{visibility:hidden}
/* One screen of nothing under the feed, so the last post can reach the top of it. A little more
   than the scroller holds, because the window is taller than the scroller by a header and a tab
   bar, and overshooting costs an empty box nobody scrolls to. */
.untail{min-height:100vh;pointer-events:none}
/* A reply you have not read says so in words — the mark alone does not tell you it is a comment. */
/* The list is a browse screen: a header with no rule, then plain rows on a 1px rule inside the
   18px gutter, the face round, the line in ink and the journal and time muted under it. Unread is
   a round accent dot at the right and the line at 600 — a mark, not a band of colour. */
.news .bar{padding:10px 12px 10px 7px;border-bottom:0;gap:8px}
/* The title is never cut: it keeps its own width and "Mark all read" gives way instead, onto two
   lines, as German and Albanian need below about 400px. */
.news .bar .h1{flex:1 0 auto;font-size:22px;letter-spacing:-.02em;white-space:nowrap}
.news .bar .btn-ghost.small{flex:0 1 auto;min-width:0;min-height:44px;padding:0 6px;font-family:var(--font-heading);font-size:13px;font-weight:800;
  white-space:normal;text-align:right;line-height:1.15}
.news .nrow{display:flex;align-items:flex-start;gap:12px;padding:12px 18px;border:0;cursor:pointer;text-align:left;
  background:linear-gradient(var(--rule),var(--rule)) center bottom / calc(100% - 36px) 1px no-repeat}
.news .nrow .body{display:flex;flex-direction:column;gap:3px;min-width:0;flex:1}
.news .nrow .t{font-size:14px;line-height:1.4;color:var(--text-2)}
.news .nrow.unread .t{color:var(--text);font-weight:600}
.news .nrow .at{font-size:12px;color:var(--muted)}
.news .nrow .mark{width:8px;height:8px;border-radius:50%;background:var(--accent);flex:none;margin-top:7px}
.news .none{padding:28px 18px;font-size:14px;line-height:1.5;color:var(--muted);max-width:36ch}
/* The banner: a card that comes down over the top of whatever is on screen, the way a phone's own
   notification does — 14px corners, the bars' colour, lifted by a shadow. What happened is in ink,
   when in the section-label caps, and Look is the soft tinted pill Home's invitations wear. It was
   an inverted slab with its two red words at 1.8:1 in the dark theme. */
.newsbar{position:absolute;left:10px;right:10px;top:calc(6px + env(safe-area-inset-top));z-index:40;display:flex;align-items:stretch;
  background:var(--bar);color:var(--text);border-radius:var(--radius-md);box-shadow:0 8px 30px rgba(0,0,0,.28),0 0 0 1px var(--rule);animation:jrNews .22s ease-out}
.jr-dark .newsbar{box-shadow:0 8px 30px rgba(0,0,0,.55),0 0 0 1px var(--rule)}
.newsbar .body{display:flex;align-items:center;gap:10px;padding:10px 4px 10px 12px;flex:1;min-width:0;cursor:pointer}
.newsbar .txt{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}
.newsbar .k{font-family:var(--font-heading);font-weight:600;font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.newsbar .t{font-size:13px;line-height:1.3;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.newsbar .look{font-family:var(--font-heading);font-weight:800;font-size:10px;letter-spacing:.08em;text-transform:uppercase;flex:none;
  padding:5px 9px;border-radius:12px;background:var(--accent-tint);color:var(--accent-tint-text)}
.newsbar .close{border:0;background:none;color:var(--muted);width:44px;padding:0;cursor:pointer;display:grid;place-items:center;border-radius:0 var(--radius-md) var(--radius-md) 0}
@keyframes jrNews{from{transform:translateY(-100%)}to{transform:translateY(0)}}
/* Pull to refresh: a strip drawn over the top of the scrolling area, revealed by the pull. */
.ptr{position:absolute;left:0;width:100%;height:40px;box-sizing:content-box;display:none;align-items:center;justify-content:center;background:var(--color-bg);z-index:25;pointer-events:none;transform:translateY(-100%)}
.ptr.at-top{padding-top:env(safe-area-inset-top)}
.ptr.live{display:flex}
.ptr.ease{transition:transform .22s ease-out}
.ptr span{font-family:var(--font-heading);font-weight:600;font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.ptr.ready span,.ptr.busy span,.ptr.warn span{color:var(--accent-text)}
.ptr i{position:absolute;left:0;bottom:-2px;height:2px;width:0;border-radius:1px;background:var(--color-accent)}
.ptr.busy i{width:100%;animation:jrPtr .9s ease-in-out infinite}
@keyframes jrPtr{0%,100%{opacity:.3}50%{opacity:1}}
/* Over everything it can be raised from, which is the only rule a toast has: it is the app
   answering, and an answer nobody can see is the same as no answer. It sat at 30, under the popup,
   so anything said from inside the popup was said underneath it. */
/* The light chip's colours, on a 14px card — the one inverted thing on a screen, so it is read. Its
   action is the accent's text colour of the *other* theme, because it sits on the other theme's
   ground: 5.9:1 on the light card in the dark theme, 6.1:1 on the dark card in the light one. */
/* No bigger than it was: the Add sheet's lower doors sit behind this spot, and a toast any taller
   covered the middle of Feeling, where a thumb lands. Its foot is 5px clear of the 71px tab bar
   (at 68 it sat 3px on the bar's rule); its top is still below Feeling's middle. */
.toast{position:absolute;left:12px;right:12px;bottom:calc(76px + env(safe-area-inset-bottom));background:var(--sel-bg);color:var(--sel-fg);font-size:13px;line-height:1.35;padding:9px 14px;border-radius:var(--radius-md);box-shadow:0 8px 30px rgba(0,0,0,.3);animation:jrToast .2s ease-out;z-index:50;display:flex;justify-content:space-between;gap:10px;align-items:center}
.toast button{border:0;background:none;color:#f07a63;font:inherit;font-family:var(--font-heading);font-weight:800;cursor:pointer;padding:0 2px;min-height:24px;flex:none}
.jr-dark .toast button{color:#b02008}
.kb .toast{bottom:12px}

/* ─── sheet ─────────────────────────────────────────────────────────────── */
/* Above the comment popup, which is the layer that raises most of these.
   The ladder, bottom to top: the popup and the news bar at 40, everything modal at 45, the toast at
   50, the full-screen photo at 60, the camera and a game at 70, the picture picker at 72. It was 20
   here, under the popup at 40 — so Remember opened from the popup's head line and was drawn behind
   it: the sheet was there, and there was no way to reach it. Every modal in the app shares this one
   backdrop, so the emoji sheet behind the plus was the same bug with nobody having tapped it yet. */
.sheet-backdrop{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:flex-end;z-index:45}
/* 9.7.4: the dimming is a layer of its own under the sheet, because it fades in and out and the
   sheet, inside the backdrop, must not fade with it. The movement is ../js/bottomsheet.js. On its
   way out the whole thing is a picture: no pointer, inert, so a tap lands on what is behind. */
.sheet-dim{position:absolute;inset:0;background:color-mix(in srgb,var(--color-neutral-900) 55%,transparent)}
.sheet-backdrop.leaving{pointer-events:none}
/* The six bottom sheets — a sheet on its own backdrop, never the What's-new drawing of one, which is
   also a .sheet and must stay as it was — wear the comment popup's look (see .cpop): 24px top
   corners, the grabber, the sheet shadow, and the bars' colour, a step off the page in either
   theme. No CSS keyframe: they come up and go down on the spring, from script. */
.sheet-backdrop>.sheet{position:relative;animation:none;border-radius:24px 24px 0 0;box-shadow:var(--sheet-shadow);
  background:var(--bar)}
.sheet{background:var(--color-bg);box-shadow:var(--shadow-lg);animation:jrSheet .22s ease-out;max-height:85%;overflow:auto;overscroll-behavior:contain;padding-bottom:env(safe-area-inset-bottom)}
.sheet-tabs{display:flex;border-bottom:2px solid var(--color-divider)}
.sheet-tabs .tab{flex:1;min-height:48px;border:0;background:none;font:inherit;font-size:13px;font-weight:600;cursor:pointer;text-align:left;padding:0 16px;color:var(--color-text);border-bottom:2px solid transparent;margin-bottom:-2px}
.sheet-tabs .tab.on{color:var(--color-accent);border-bottom-color:var(--color-accent)}
.sheet-tabs .icon-btn{width:48px;height:48px}
.sheet-body{padding:14px 16px;display:grid;gap:12px}
/* Taking a post down lives under the two things you are more likely to want, behind a rule,
   so it is never the button your thumb finds first. */
.sheet-foot{padding:10px 16px 14px;border-top:2px solid var(--color-divider)}
.sheet-foot .btn{margin:0}
.sheet-body.tight{gap:8px}
.sheet .lbl{font-size:12px;margin-bottom:6px;color:var(--color-neutral-600)}
.crow{min-height:48px;padding:0 12px;text-align:left;border:1px solid var(--color-divider);background:transparent;color:var(--color-text);font:inherit;font-size:14px;font-weight:600;cursor:pointer;display:flex;justify-content:space-between;align-items:center}
.crow.on{background:var(--color-text);color:var(--color-bg);border-color:var(--color-text)}
.crow span{font-size:11px;font-weight:400;opacity:.8}
/* The Remember sheet (sheet.js) is not in the design; it is drawn in the design's language. Its two
   modes are two chips across the top with a round close beside them rather than underlined tabs;
   labels are the small capitals; the fields and the people are filled; a curated journal is a
   filled row; and the two quieter things at the foot are filled rows under a soft rule, taking the
   post down in the accent's text colour. Scoped to the one sheet: the install sheet wears the
   same .sheet-body and .sheet-foot. */
.remsheet .sheet-tabs{display:flex;align-items:center;gap:6px;padding:21px 14px 4px 14px;border:0}
/* 44 to hit, drawn 40: a 2px clear edge above and below with the fill clipped inside it. */
.remsheet .sheet-tabs .tab{flex:1 1 0;min-width:0;min-height:44px;margin:0;padding:0 10px;
  border:solid transparent;border-width:2px 0;border-radius:14px/16px;
  background-color:var(--surface-1);background-clip:padding-box;color:var(--text-2);font-family:var(--font-heading);font-size:13px;font-weight:800;text-align:center;
  line-height:1.15;overflow-wrap:anywhere}
.remsheet .sheet-tabs .tab.on{background-color:var(--sel-bg);color:var(--sel-fg)}
.remsheet .sheet-tabs .icon-btn{flex:none;width:44px;height:44px;margin-left:4px;padding:5px;border:0;
  background-color:var(--surface-1);background-clip:content-box;color:var(--text)}
.remsheet .sheet-body{padding:14px}
.remsheet .sheet-body>.muted{padding:0 4px}
.remsheet .lbl,.remsheet .field>label{margin:0 4px 8px;font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.remsheet .chip.av{padding-left:5px;border-radius:20px}
.remsheet .crow{min-height:50px;padding:0 16px;border:0;border-radius:var(--radius-md);background:var(--surface-1);color:var(--text);font-weight:800}
.remsheet .crow.on{background:var(--sel-bg);color:var(--sel-fg)}
.remsheet .crow span{font-weight:600;opacity:1;color:inherit}
.remsheet .sheet-foot{padding:10px 14px 14px;border-top:1px solid var(--rule);display:grid;gap:6px}
.remsheet .sheet-foot .btn{min-height:48px;padding:0 16px;gap:10px;border:0;border-radius:var(--radius-md);
  background:var(--surface-1);color:var(--text);font-weight:800}
.remsheet .sheet-foot .btn.danger{color:var(--accent-text)}
.remsheet .jsheet-danger{padding:24px 14px 14px}
.remsheet .jsheet-danger .btn-ghost{background:var(--surface-1);color:var(--text);justify-content:center}

/* ─── onboarding ─────────────────────────────────────────────────── */
/* Ten steps. Counter, progress rule and footer are pinned; only .intro-body scrolls. */
.intro{flex:1;display:flex;flex-direction:column;min-height:0;padding:28px 20px 24px;padding-top:calc(28px + env(safe-area-inset-top));padding-bottom:calc(24px + env(safe-area-inset-bottom))}
.intro .top{display:flex;justify-content:space-between;align-items:center;font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);flex:none}
.intro .top .btn-ghost{padding:8px 4px;min-height:44px;font-family:var(--font-heading);font-size:13px;font-weight:800;text-transform:none;letter-spacing:0}
/* A rounded track and its fill, as the design's bars are drawn — not a 2px rule. */
.intro .prog{height:4px;border-radius:2px;background:var(--surface-2);margin:12px 0 0;position:relative;flex:none;overflow:hidden}
.intro .prog i{position:absolute;left:0;top:0;height:4px;border-radius:2px;background:var(--color-accent);transition:width .2s}
/* Negative margin + matching padding so the illustrations are never clipped at the edge. */
.intro-body{flex:1;min-height:0;padding:28px 4px 16px;margin:0 -4px}
.intro h1{font-family:var(--font-heading);font-weight:800;font-size:40px;line-height:1.02;letter-spacing:-.03em;margin:0 0 12px}
.intro p{font-size:16px;margin:0;max-width:30ch;line-height:1.5;color:var(--text-2)}
.intro .form{display:grid;gap:14px}
.intro .form .field>label{display:block;margin:0 2px 8px;font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.intro .form .input{min-height:48px}
.intro .swap{font-size:13px;color:var(--muted);margin-top:14px}
.intro .swap button{border:0;background:none;color:var(--accent-text);font:inherit;font-weight:800;cursor:pointer;padding:0;min-height:44px}
.intro .err{font-size:13px;color:var(--accent-text);margin-top:12px;padding:10px 14px;border-radius:var(--radius-md);background:var(--surface-1)}

/* footer: ten tappable segments, then back + primary. The segments are the progress bar's own
   rounded pieces, each still hit 26px tall. */
.intro .dots{display:flex;gap:4px;margin-bottom:16px;flex:none;height:4px}
.intro .dots button{flex:1;height:4px;padding:0;border:0;border-radius:2px;background:var(--surface-2);cursor:pointer;position:relative}
.intro .dots button.on{background:var(--text-2)}
.intro .dots button::after{content:"";position:absolute;left:0;right:0;top:-11px;bottom:-11px}
.intro .cta-row{display:flex;gap:8px;flex:none}
.intro .back{width:48px;height:48px;flex:none;padding:0}
.intro .cta{min-height:48px;margin:0;border-radius:var(--radius-md);font-family:var(--font-heading);font-weight:800;padding:0 18px}
.intro .cta svg{margin-left:auto}

/* The illustrations draw the app as it now is: tiles with 14px corners on the surface, words as
   filled chips, the day's numeral with its hand-written weekday beside it, chips over pictures
   solid and white, faces round. Nothing tilted, no tape, no paper frame. */
.intro .collage{display:grid;grid-template-columns:repeat(6,1fr);gap:8px;margin-bottom:28px}
.intro .collage.start{align-items:start}
.intro .collage.mid{align-items:center}
.intro .tape{display:none}
.intro .frame{background:var(--surface-1);border-radius:var(--radius-md)}
/* fit-content, not max-content: a max-content chip widens the drawing's grid column to its whole
   line and runs under the card beside it (German at 320); this one wraps inside its column instead. */
.intro .lab{background:var(--surface-1);color:var(--text);font-family:var(--font-heading);font-weight:800;font-size:10px;letter-spacing:.1em;text-transform:uppercase;padding:8px 10px;border-radius:var(--radius-md);width:fit-content;max-width:100%}
.intro .plus{aspect-ratio:1;border-radius:var(--radius-md);background:var(--accent-fill);color:var(--on-accent);display:grid;place-items:center;font-family:var(--font-heading);font-weight:800;font-size:22px}
.intro .stamp{border:0;border-radius:var(--radius-md);background:var(--surface-1);color:var(--text);padding:8px 12px}
.intro .stamp .num{color:var(--accent-text)}
.intro .stamp .of{color:var(--muted)}
.intro .mini-date{display:flex;align-items:baseline;gap:8px}
.intro .mini-date .n{font-family:var(--font-heading);font-weight:800;font-size:30px;line-height:1;letter-spacing:-.04em}
.intro .mini-date .hw{font-family:'Caveat',cursive;font-weight:700;font-size:21px;line-height:1;color:var(--hand)}
.intro .mini-polaroid{position:relative;background:var(--surface-2);border-radius:var(--radius-md);overflow:hidden}
.intro .mini-polaroid.sm{border-radius:12px}
.intro .mini-polaroid .box{background:var(--surface-2)}
.intro .mini-polaroid .from{position:absolute;left:5px;top:5px;border-radius:6px;background:rgba(28,26,25,.72);color:#fff;font-family:var(--font-heading);font-weight:800;font-size:7px;letter-spacing:.08em;text-transform:uppercase;padding:3px 5px;white-space:nowrap}
.intro .mapcard{border-radius:var(--radius-md);overflow:hidden}
.intro .mini-legend{display:flex;gap:10px;font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin-top:6px}
.intro .mini-legend span{display:flex;align-items:center;gap:5px}
.intro .mini-legend i{width:8px;height:8px;border-radius:50%;display:block}
.intro .mini-legend i.a{background:var(--color-accent)}
.intro .mini-legend i.b{background:var(--color-text)}
.intro .hold{font-size:10px;color:var(--muted);padding-left:4px}
.intro .mini-card{background:var(--surface-1);border-radius:var(--radius-md);padding:10px 12px}
.intro .mini-card .hd{display:flex;align-items:center;gap:6px;border-bottom:1px solid var(--rule);padding-bottom:7px;margin-bottom:7px}
.intro .mini-card .hd b{font-family:var(--font-heading);font-weight:800;font-size:12px}
.intro .mini-card .row{font-size:10px;line-height:1.5;color:var(--text-2)}
.intro .mini-card .dash{color:var(--accent-text);font-weight:800}
.intro .mini-tag{font-size:8px;width:max-content;border:0;border-radius:var(--radius-sm);background:var(--surface-1);color:var(--text-2);font-weight:800}
.intro .mini-lock{width:22px;height:22px;border-radius:50%;background:var(--surface-1);display:grid;place-items:center;color:var(--text)}
.intro .mini-mix{display:flex;align-items:center;gap:10px;margin-top:4px;font-size:12px;color:var(--muted)}
.intro .mini-mix .sq{width:36px;height:36px;flex:none;border-radius:12px;background:var(--accent-fill);color:var(--on-accent);display:grid;place-items:center}
.intro .mini-invite{display:flex;align-items:center;gap:8px;background:var(--surface-1);border-radius:var(--radius-md);padding:8px 8px 8px 14px}
.intro .mini-invite .code{flex:1;font-family:var(--font-heading);font-weight:800;font-size:16px;letter-spacing:.06em;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.intro .mini-invite .share{min-height:32px;font-size:12px;flex:none;border-radius:12px}
.intro .mini-avatars{display:flex;gap:4px;margin-top:4px}
.intro .mini-avatars .add{width:24px;height:24px;border-radius:50%;background:var(--surface-1);color:var(--muted);display:grid;place-items:center;font-size:12px}

/* people who were invited but have not joined: a "?" in the roster */
.pending-av{display:grid;place-items:center;flex:none;border-radius:50%;border:1.5px dashed var(--color-neutral-600);color:var(--color-neutral-600);font-family:var(--font-heading);font-weight:800;line-height:1;background:none}
.btn.left{justify-content:flex-start;text-align:left}
.btn.danger{color:var(--accent-text)}

/* ─── journal settings sheet ────────────────────────────────────────────── */
/* A sheet in the design's language, like Remember: a head with the journal's own thumbnail (46px,
   12px corners, as Home's rows draw it) and a round close; sections separated by space and labelled
   in the small capitals rather than ruled off at 2px; members as a ruled list; the cover a card with
   corners and nothing tilted. Export, Leave and Delete are filled rows, Delete in the accent's
   text colour. */
.jsheet{max-height:88%}
.jsheet-hd{display:flex;align-items:center;gap:12px;padding:21px 14px 8px 18px;border:0}
.jsheet-hd .thumb{width:46px;height:46px;flex:none;position:relative;border-radius:12px;background:var(--surface-2);overflow:hidden}
.jsheet-hd .thumb img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.jsheet-hd .ttl{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.jsheet-hd .k{font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.jsheet-hd .name{font-family:var(--font-heading);font-weight:800;font-size:20px;line-height:1.2;letter-spacing:-.02em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.jsheet-hd .icon-btn{padding:4px;background-color:var(--surface-1);background-clip:content-box;color:var(--text)}
.jsheet-sec,.jsheet .sec{padding:14px 18px;border:0;display:grid;gap:12px}
.jsheet-sec .k,.jsheet .sec .k{font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.jsheet .sec .lbl{margin:0;font-size:13px;line-height:1.45;color:var(--text-2)}
/* Cover art beside the name, so both are changed in the same place. */
.jsheet-sec .coverrow{display:flex;gap:14px;align-items:flex-start}
.jsheet-sec .coverslot{width:72px;flex:none;position:relative;cursor:pointer;border-radius:var(--radius-md);background:var(--surface-2)}
.jsheet-sec .coverslot .media-box{aspect-ratio:3/4;border-radius:var(--radius-md)}
.jsheet-sec .coverslot .edit{position:absolute;right:-6px;bottom:-6px;width:28px;height:28px;border-radius:50%;background:var(--sel-bg);color:var(--sel-fg);display:grid;place-items:center;box-shadow:0 0 0 2px var(--bar)}
.jsheet-sec .coverrow .field{flex:1;min-width:0}
.jsheet-sec .field>label{font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin:0 2px 8px}
.jsheet-sec .coveracts{display:flex;flex-wrap:wrap;gap:4px;margin-top:6px}
.jsheet-sec .coveracts .btn{padding:0 6px;min-height:32px;font-weight:800}
.jsheet-sec .note,.jsheet-acts .note{font-size:12px;line-height:1.45;color:var(--muted)}
.jsheet-acts .note{padding:6px 4px 0}
.mrows{display:flex;flex-direction:column}
.mrow{display:flex;align-items:center;gap:12px;min-height:48px;border-top:1px solid var(--rule);font-size:15px}
.mrows .mrow:first-child{border-top:0}
.mrow .n{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mrow .role{font-size:12px;color:var(--muted);flex:none}
.mrow .pending-av{width:24px;height:24px;font-size:11px}
.jsheet .btn-secondary.left{border-radius:var(--radius-md);font-weight:800;padding:0 16px;gap:10px}
.jsheet-acts{padding:8px 18px 18px;display:grid;gap:6px}
.jsheet-acts .btn{min-height:48px;margin:0;padding:0 16px;border:0;border-radius:var(--radius-md);background:var(--surface-1);color:var(--text);font-weight:800}
.jsheet-acts .btn.danger{color:var(--accent-text)}
.jsheet-danger{padding:22px 18px 16px;display:grid;gap:14px}
.jsheet-danger .ttl{font-family:var(--font-heading);font-weight:800;font-size:22px;line-height:1.1;letter-spacing:-.02em}
.jsheet-danger p{margin:0;font-size:14px;line-height:1.45;color:var(--text-2)}
.jsheet-danger .field>label{font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin:0 2px 8px}
.jsheet-danger .btn-ghost{margin:0;padding:0 16px;border-radius:var(--radius-md);background:var(--surface-1);color:var(--text);font-weight:800}
/* Not yet: the name is not typed. Still a button (a tap says what is missing), drawn on the surface
   rather than as the red faded to .45, which left its words at 2.1:1 (light) and 2.6:1 (dark). */
.jsheet-danger .btn-primary.notyet{background:var(--surface-1);color:var(--muted)}

/* ─── home ──────────────────────────────────────────────────────────────── */
/* The header: title left, then a 38px bell drawn as a rounded square, Join on the surface and New
   in the one red the screen spends. Everything on Home sits on the 18px list gutter. */
.home .hdr{padding:22px 14px 10px 18px;align-items:center;gap:6px}
.home .hdr .h1{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding-bottom:3px;margin-bottom:-3px}
.home .hdr-acts{display:flex;align-items:center;gap:6px}
/* Drawn 38, hit 44: a 3px clear edge with the fill clipped inside it, taken back out of the row by
   the margins so the header is laid out as though the buttons were 38. */
.home .hdr-acts .btn{min-height:44px;height:44px;margin:-3px 0;padding:0 13px 0 11px;gap:6px;
  border:solid transparent;border-width:3px 0;border-radius:14px/17px;background-clip:padding-box;
  font-size:13px;font-weight:800;line-height:1}
.home .hdr-acts .bellbtn{width:44px;margin:-3px;padding:0;border-width:3px;border-radius:17px}
/* The drawing is English at 360. German's Beitreten does not fit beside the title there, so in any
   other language under 390px — 375 itself cut "Journale" by 4px — and in every language under 360,
   Join gives up its icon and the gaps close. Past that (German at 320) the title ellipsises rather
   than being covered; every button stays on the screen either way. */
@media (max-width:389px){
  :root:not(:lang(en)) .home .hdr,:root:not(:lang(en)) .home .hdr-acts{gap:4px}
  :root:not(:lang(en)) .home .hdr-acts .btn:not(.bellbtn){padding:0 11px}
  :root:not(:lang(en)) .home .hdr-acts .btn-secondary:not(.bellbtn) svg{display:none}
}
@media (max-width:359px){
  .home .hdr,.home .hdr-acts{gap:4px}
  .home .hdr-acts .btn:not(.bellbtn){padding:0 11px}
  .home .hdr-acts .btn-secondary:not(.bellbtn) svg{display:none}
}
.empty.stack{display:grid;gap:14px;justify-items:start}
/* The posters used to sit inside a titled section that carried the side padding. There is no
   section any more, so the padding is on the grid — and it has to be there, not on .home, because
   the rows below it and the chips above it set their own. */
.home .covers{padding:12px 18px}
.covers{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
/* A cover is a card: the picture on top at 6:5, the name and the line under it on the surface,
   corners 14 and nothing lifting it off the page. */
.coverbtn{cursor:pointer;display:flex;flex-direction:column;gap:0;min-width:0;border-radius:14px;overflow:hidden;background:var(--surface-1)}
.coverbtn .cover{position:relative;display:flex;flex-direction:column}
.coverbtn .cover .media-box{position:relative;width:100%;aspect-ratio:6/5}
.coverbtn .cover .title{padding:8px 11px 0;display:flex;flex-direction:column;align-items:flex-start;pointer-events:none}
.coverbtn .cover .title span{font-family:var(--font-heading);font-weight:800;font-size:14px;line-height:1.25;color:var(--color-text);max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cover-meta{display:flex;align-items:center;gap:6px;font-size:12px;min-width:0;padding:3px 11px 10px}
.cover-meta .last{color:var(--muted);flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* On the picture, so drawn as the tiles' chip: solid, round, white. Scoped to Home's card, because
   .cover is also a class on the composer's Cover it tool, and an unscoped .cover rule reaches it. */
.coverbtn .cover .lock{border-radius:50%;background:rgba(28,26,25,.72);color:#fff}
.home .none{font-size:13px;color:var(--color-neutral-600);padding:24px 18px}
.home .hint{padding:16px 18px}
/* The last-used strip is gone. It was a row of the same covers at 92px above the sections, and it
   drew every journal a second time — which is half of why this screen measured seven screens of
   scrolling. The list is ordered by exactly what that strip was ordered by now, so the strip was
   the answer sitting on top of the question. */

/* ─── journal ───────────────────────────────────────────────────────────── */
.jhead{padding:12px 8px 0 11px}
.jhead .row1{display:flex;align-items:center;gap:7px}
.jhead .row1 .ttl{flex:1;min-width:0}
/* The name never loses. Whatever is beside it is fixed width and shrinks to nothing before the
   title gives up a character — it used to be the other way round, which is how a journal came to
   be called "sku…". */
.jhead .row1 .who{display:flex;align-items:center;gap:5px;flex:none}
/* Overlapping, so three faces cost the width of two: 26px each in a 2px ring of the page, 22px
   apart, the way the design draws them. */
.jhead .who .stack{display:flex}
.jhead .who .stack > *{margin-left:-4px;box-shadow:0 0 0 2px var(--page)}
.jhead .who .stack > *:first-child{margin-left:0}
.jhead .who .rest{font-size:11px;font-weight:800;color:var(--text-2);font-variant-numeric:tabular-nums}
.jhead .row1 .h1{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:26px;font-weight:800;letter-spacing:-.03em;line-height:1.15}
.jhead .row2{display:flex;align-items:center;justify-content:space-between;padding:8px 0 0 8px;gap:8px}
/* Which view, on the line the members' names had: the composer's kind pill (.cshell .chead .kind
   span) under the name and flush with it, hit at 44 and drawn at 20, and the composer's list
   (.kindlist) when it is tapped. Pulled up 6px into the title's row, under the name, where nothing
   else is hit. The label never gives way: it has the whole line. */
.jhead .jview{display:flex;align-items:center;min-height:44px;margin:-6px 0 0 51px;padding:0;border:0;background:none;
  color:var(--text-2);font:inherit;cursor:pointer;text-align:left}
.jhead .jview span{display:inline-block;padding:4px 8px;border-radius:14px;background:var(--surface-1);
  font-family:var(--font-heading);font-weight:800;font-size:10px;line-height:12px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--text-2);white-space:nowrap}
.jhead .jview span svg{display:inline-block;vertical-align:-1px;margin-left:3px}
.ttabs button{min-height:40px;padding:0 12px;border:0;background:none;cursor:pointer;font:inherit;font-size:13px;font-weight:600;color:var(--color-text);border-bottom:2px solid transparent;margin-bottom:-2px}
/* Five tabs and the member line will not share one row on a phone: the names lost, one letter at a
   time, until they read "A…". The tabs take the row to themselves and scroll if even that is tight;
   the names keep their own line above. */
@media (max-width:520px){
  .jhead .row2{display:block;padding-left:0}
  .ttabs{overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
  .ttabs::-webkit-scrollbar{display:none}
  .ttabs button{padding:0 11px;flex:none}
}
/* A curated journal's rules, under the tabs: a row of filled chips on the head's own ground, in the
   18px gutter, with no rule under it — not outlined tags in the accent on a band of their own. */
.fills{padding:2px 18px 12px;border:0;background:none;display:flex;flex-wrap:wrap;gap:6px;align-items:center}
.fills .k{font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin-right:4px}
.fills .tag{min-height:26px;padding:0 10px;border:0;border-radius:var(--radius-sm);background:var(--surface-1);color:var(--text-2);
  font-size:12px;font-weight:700;letter-spacing:0}

/* spreads: a desk, a sheet per day, bands inside a sheet, rows against a time margin */
/* The desk, with the browser's own scroll bar and nothing of ours.
   There was a rail down the right edge for five rounds: a track, a thumb, a mark per unread post,
   counts at the ends. Asked for directly, and rightly — sixteen pixels cannot be a scroll bar, a
   map of the unread and a row of tap targets at the same time, and being all three badly is worse
   than being one of them well. The phone draws a scroll bar; what is unread is on the posts. */
/* The positioning context for the dots below, and nothing else. */
.deskwrap{flex:1;display:flex;flex-direction:column;min-height:0;position:relative}
/* The scroller and the dots beside it, under whatever the bar above them is saying. */
.deskbody{flex:1;display:flex;flex-direction:column;min-height:0;position:relative}
/* And the desk shows it. Every scroller in the app hides its bar (.scroll) because on short lists
   it is furniture — but the spread is the one place in here you can scroll for a minute without
   the screen telling you where you are, which is the complaint the rail was built to answer and
   never did. The native one is thin, fades when you stop, and is the one the phone's owner already
   knows how to read. */
/* Where the unread posts are, beside the bar rather than on it.
   The strip's own `right` is written by the measuring (the browser's bar is a real column in a
   desktop window and an overlay on a phone), and the dots sit a few pixels inboard of that again.
   Nothing here takes a pointer event: this says where, the scroll bar does the scrolling, and a
   target big enough to tap on this edge is a target big enough to swallow the pull-to-refresh. */
.newsdots{position:absolute;top:0;bottom:0;width:18px;z-index:4;pointer-events:none}
.newsdots .dot{position:absolute;right:5px;width:4px;height:8px;margin-top:-4px;border-radius:2px;
  background:var(--color-accent);display:block;transition:height .12s linear,margin-top .12s linear}
/* Its post is on the screen in front of you. The dot doubles to say so — a yes or no you can read
   at any length of journal, which a position on a 900px strip cannot.
   It doubles in *height* now rather than in width, and that is the whole reason the cards could be
   given room. It cannot grow outwards: on a phone the browser's bar is an overlay drawn over the
   last few pixels of the content, so a mark that grew that way would end up underneath it at
   exactly the moment somebody is scrolling and looking. So it used to grow inwards instead, which
   put its left edge 23px from the screen edge — and a tile is tilted, so it is painted up to about
   4px wider than it is laid out. The two together left roughly a pixel between an expanded mark
   and the corner of a tall note, before any of this was narrowed. Growing the other way says the
   same thing, costs the cards nothing, and the mark stays exactly where it was pointing. */
.newsdots .dot[data-here]{height:16px;margin-top:-8px}
@media (prefers-reduced-motion:reduce){.newsdots .dot{transition:none}}

.desk{scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--color-text) 35%,transparent) transparent}
.desk::-webkit-scrollbar{display:block;width:6px}
.desk::-webkit-scrollbar-track{background:transparent}
.desk::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--color-text) 35%,transparent)}

/* Voice, links and places have no meta row of their own; theirs appears under the tile. */
.meta.under{padding:5px 2px 0}
/* An unliked post in a solo journal has neither an avatar nor a like group, so the row must take no
   room at all: nothing about the tile may move until a like actually lands. */
.meta:empty{display:none}

/* The heart that lands when you double-tap: big, brief, and gone. It is not a control, so nothing
   can be tapped through it. */
.beat{position:absolute;left:50%;top:50%;z-index:4;line-height:0;pointer-events:none;
  animation:jrHeart .62s ease-out forwards}
@keyframes jrHeart{
  0%{opacity:0;transform:translate(-50%,-50%) scale(.6)}
  22%{opacity:1;transform:translate(-50%,-50%) scale(1.08)}
  45%{transform:translate(-50%,-50%) scale(1)}
  100%{opacity:0;transform:translate(-50%,-64%) scale(1)}
}
@media (prefers-reduced-motion:reduce){.beat{animation:none;opacity:0}}

/* Who said something, in words, under the chips. The chips carry the counts and their tooltips
   carry the names, but a phone has no hover and "who" is most of what a reaction is for. */
.saidby{margin-top:7px;font-size:12px;color:var(--color-neutral-700)}
/* The spread's video preview: the moving picture over the still one, fading in when it is this
   tile's turn. It carries no src until then, so a sheet of videos downloads none of them. */
.media-box .reel{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;
  opacity:0;transition:opacity .18s ease-out;pointer-events:none;background:transparent}
.media-box .reel.on{opacity:1}
/* While it is playing, the duration badge stops shouting Play at something already playing. */
.polaroid .play.quiet svg{display:none}
/* The picture stops well short of filling the screen, so the caption, the says and the four
   actions are all in the first look instead of being a scroll away. Tall photos are the ones that
   used to push everything off: capped by height, they keep their shape and give the page back. */
/* Your own picture in Me is a button, and must look like exactly what it replaced. */
.mephoto{appearance:none;background:none;border:0;padding:0;margin:0;line-height:0;cursor:zoom-in}
/* A post that is on the spread but not yet on the server. It is dimmed rather than hidden, and it
   says which it is: an upload still going, or one that did not. Nothing about it is disabled —
   the whole point is that the app carries on being usable while the bytes go. */
.tile.sending{opacity:.72}
.tile.sending .sendmark,.tile.didnt .sendmark{position:absolute;right:8px;top:8px;z-index:4;border-radius:10px;
  font-family:var(--font-heading);font-weight:800;font-size:9px;letter-spacing:.08em;text-transform:uppercase;
  padding:4px 8px;background:var(--color-text);color:var(--color-bg);box-shadow:var(--shadow-sm)}
/* The deeper red in both themes, as the coded cover label: --color-accent-800 is the soft accent
   since the softer palette, #f07a63 in the dark theme, and white 9px on it was 2.5:1. On this, 5.1. */
.tile.didnt .sendmark{background:#d42a10;color:#fff}
.tile.didnt{outline:1px solid #d42a10;outline-offset:2px}
.mephoto:focus-visible{outline:2px solid var(--color-accent);outline-offset:2px}
/* Nothing behind the picture but the page. Capping a tall photo's height makes its box narrower
   than the screen — the aspect ratio derives the width — and a block box at auto width sits hard
   against the left, with the ground showing beside it as a grey band. Centred, and the ground is
   not painted at all: on this screen there is the photograph and there is nothing else. */
.hero-shot{position:relative;cursor:zoom-in;line-height:0}
.hero-shot .media-box{max-height:56vh;margin-inline:auto;background:none}
/* `contain` rather than the usual `cover`: a capped tall photo would otherwise lose its top and
   bottom, and this is the screen where the whole picture is the point. */
.hero-shot .media-box img{object-fit:contain}
@media (prefers-reduced-motion:no-preference){.hero-shot .media-box img{animation:heroin .18s ease-out}}
@keyframes heroin{from{opacity:.001}to{opacity:1}}
/* A video is capped the same way a photo is, and so has to be centred the same way: capping the
   height makes the box narrower than the screen, and a block box at auto width sits on the left. */
.detail .media-box{max-height:56vh;margin-inline:auto;background:none}
.detail .media-box video{object-fit:contain}
/* Tighter without being cramped: this is the part of the screen that was all padding. */
.detail .saidby{margin-top:6px}
/* The scroller keeps its momentum on iOS and stops the page behind it moving with it. */
.detail .scroll{-webkit-overflow-scrolling:touch;overscroll-behavior:contain;scroll-behavior:auto}
/* ─── the spread: a mosaic ───────────────────────────────────────────────────

   A day is its heading and a grid of two columns, on the page's own ground: no desk behind it, no
   sheet of paper, no rule across the top. What separates one day from the next is the heading.
   The desk and the day share the page colour on purpose — a rounded tile on a ground of another
   colour shows that colour in its corners, and the big feed's deck turns a card across exactly
   those corners.

   The gutter is 14px a side, the design's for a grid of cards. The marks beside the scroll bar
   (.newsdots) cost no width but need room: a mark is 4px wide, 5px in from the edge, so it clears
   a tile by five. */
.desk{flex:1;position:relative;background:var(--page);padding:2px 0 28px}
.daysheet{background:none;padding:0 0 12px}
/* The day: the numeral, the weekday and month by hand beside it, how much is on it at the far
   end. Caveat for the hand, which is the one place it is used. Its descenders hang 2px below a
   line-height of 1, and the clip that makes the ellipsis took them (the y of "today", the p of
   "pre"): 3px of room below, given back by the margin so the heading does not move. */
.datestamp{display:flex;align-items:baseline;gap:9px;padding:8px 18px 10px}
.datestamp .n{flex:none;font-family:var(--font-heading);font-weight:800;font-size:30px;line-height:.9;letter-spacing:-.04em;color:var(--text)}
.datestamp .hw{flex:1;min-width:0;font-family:'Caveat',cursive;font-weight:700;font-size:21px;line-height:1;color:var(--hand);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding-bottom:3px;margin-bottom:-3px}
.datestamp .cnt{flex:none;font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);
  font-variant-numeric:tabular-nums}
/* What it was doing where a post was made. It rides the post's own chips and byline, never the
   day: two people on one afternoon can be under two skies. A note, not a mark. */
.wx{display:inline-flex;align-items:center;gap:2px;color:var(--color-neutral-600);vertical-align:-2px}
.wx b{font-family:var(--font-heading);font-weight:800;font-size:11px;letter-spacing:-.01em;font-variant-numeric:tabular-nums}
.detail .who .wx{margin-left:7px;color:var(--color-neutral-700)}

/* The grid. Shapes come from the packer (store/spread.js, mosaicOf) and the grid only lays them out
   in turn — never `dense`, which back-fills and so reads tiles out of order and moves them about
   whenever a post arrives. Rows are 148px where a picture sets them and as tall as their words
   where a card does; a two-row picture is two of them and the gap. */
.mosaic{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:8px;align-items:start;padding:0 14px}
.mosaic>[data-shape=w1h1]{height:148px}
.mosaic>[data-shape=w1h2]{grid-row:span 2;height:304px}
.mosaic>[data-shape=w2h1]{grid-column:span 2;height:148px}
.mosaic>[data-shape=full]{grid-column:span 2}

/* ─── a tile ─────────────────────────────────────────────────────────────────
   Rounded, and cut to its corners. The ring that says something is unread is a shadow outside the
   box (see "Unread is on the tile"), so the cut never takes it. */
.avatar.edge{outline:1px solid var(--color-divider);outline-offset:-1px}
.tile{position:relative;min-width:0;cursor:pointer;width:100%;border-radius:var(--radius-md);overflow:hidden}
.tile.stepped,.scard.stepped{opacity:.42}

/* A picture: the photograph to the edge, cut to the cell. Its ground is the dark of a photo well in
   either theme, because everything laid over it — the face, the caption, the chips — is drawn for
   a photograph, which is dark more often than not, and a scrim. */
.tile .polaroid{position:relative;height:100%;background:#151413;color:#fff}
.tile .polaroid .media-box{background:var(--surface-1)}
.mosaic>[data-shape^=w] .polaroid .media-box{position:absolute;inset:0;height:auto}
/* Across the width it keeps its own shape, between a row and the cap. Upright pictures meet the
   cap; the cut is taken high (--focus) so it takes sky rather than heads. */
.tile[data-shape=full] .polaroid .media-box{width:100%;min-height:148px;max-height:420px}
.tile .media-box img,.tile .media-box video{object-position:var(--focus,50% 50%)}
.tile .polaroid .play{position:absolute;left:8px;bottom:8px;z-index:3;display:flex;align-items:center;gap:5px;height:24px;
  padding:0 8px;border-radius:12px;background:rgba(28,26,25,.72);color:#fff;font-family:var(--font-heading);font-weight:800;
  font-size:11px;letter-spacing:.02em;pointer-events:none;font-variant-numeric:tabular-nums}
/* Who took it, in the corner: 24px and a 2px ring, the design's 28. Not a control — a tap here is
   a tap on the picture — and never what a pinch opens (data-nozoom). */
.tile .oface{position:absolute;left:10px;top:10px;z-index:3;line-height:0;border-radius:50%;box-shadow:0 0 0 2px #fff;pointer-events:none}
.tile .otime{position:absolute;right:8px;top:8px;z-index:3;padding:3px 8px;border-radius:10px;background:rgba(28,26,25,.72);color:#fff;
  font-family:var(--font-heading);font-weight:800;font-size:11px;line-height:1.3;font-variant-numeric:tabular-nums;pointer-events:none}
/* A curated journal's pick says where it came from, beside the face. */
.tile .polaroid .from{position:absolute;left:8px;top:8px;z-index:3;max-width:calc(100% - 16px);padding:4px 8px;border-radius:10px;
  background:rgba(28,26,25,.72);color:#fff;font-size:9px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;pointer-events:none}
.tile .polaroid .oface~.from{left:42px;top:12px;max-width:calc(100% - 50px)}
/* The words under a picture: two lines at most, white, on the scrim at the foot, above the chips.
   The scrim is drawn only where there are words to read. A name in them is still a link.
   It is measured from the words and not from the tile: two lines end 38px up and start 73px up,
   so the scrim is 112px tall and already .6 dark 30px into it — 9px above the first line. White
   13px words on a white photograph are then 5:1 or better on both lines in every cell. Measured
   as a share of the tile it was a quarter dark behind the first line of a 148px cell: 1.8:1. */
.tile .polaroid.hascap::after{content:'';position:absolute;left:0;right:0;bottom:0;height:min(100%,112px);z-index:1;pointer-events:none;
  background:linear-gradient(rgba(0,0,0,0),rgba(0,0,0,.6) 30px,rgba(0,0,0,.72))}
.tile .polaroid .cap{position:absolute;left:10px;right:10px;bottom:38px;z-index:2;padding:0;color:#fff;font-size:13px;line-height:1.35;
  text-shadow:0 1px 2px rgba(0,0,0,.45);display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;
  overflow-wrap:anywhere;pointer-events:none}
.tile .polaroid .cap a.mention{color:#fff;text-decoration:underline;pointer-events:auto}
/* The two chips at the foot: what was said, summed (see ReactSum), and the thoughts. Solid — no
   frosted glass on a tile: one blurred chip per tile is a layer each in a scroller of hundreds, and
   every one of them would be re-sampled through the deck's turn and the comment popup's recede. */
.tile .polaroid>.meta,.tile .t-place>.meta,.tile .t-sticker>.meta{position:absolute;left:0;right:0;bottom:0;z-index:3;margin:0;padding:6px;
  display:flex;flex-wrap:nowrap;justify-content:flex-end;align-items:center;gap:4px;pointer-events:none}
.tile .polaroid>.meta>*,.tile .t-place>.meta>*,.tile .t-sticker>.meta>*{pointer-events:auto}
.tile .polaroid>.meta .rxrow,.tile .t-place>.meta .rxrow,.tile .t-sticker>.meta .rxrow{flex:none;margin:0;gap:0}
.tile .polaroid>.meta .rxtally,.tile .t-place>.meta .rxtally,.tile .t-sticker>.meta .rxtally,
.tile .polaroid>.meta .cbtn,.tile .t-place>.meta .cbtn,.tile .t-sticker>.meta .cbtn,
.tile .polaroid>.meta .wx,.tile .t-place>.meta .wx,.tile .t-sticker>.meta .wx{height:24px;min-width:24px;margin:0;padding:0 8px;gap:4px;border:0;
  border-radius:12px;background:rgba(28,26,25,.72);color:#fff;vertical-align:0}
.tile .polaroid>.meta .rxtally.mine,.tile .t-place>.meta .rxtally.mine,.tile .t-sticker>.meta .rxtally.mine{background:#3a1a14;color:#ff6a4f}
.tile .polaroid>.meta .rxtally.none,.tile .t-place>.meta .rxtally.none,.tile .t-sticker>.meta .rxtally.none{padding:0;width:24px;justify-content:center}
.tile .polaroid>.meta .cbtn:not(:has(b)),.tile .t-place>.meta .cbtn:not(:has(b)),.tile .t-sticker>.meta .cbtn:not(:has(b)){padding:0;width:24px}
.tile .polaroid>.meta .rxtally .e,.tile .t-place>.meta .rxtally .e,.tile .t-sticker>.meta .rxtally .e{font-size:12px}
.tile .polaroid>.meta b,.tile .t-place>.meta b,.tile .t-sticker>.meta b{font-family:var(--font-heading);font-size:11px;font-weight:800}
.tile .polaroid>.meta .cbtn .nm,.tile .t-place>.meta .cbtn .nm,.tile .t-sticker>.meta .cbtn .nm{top:-2px;right:-2px;border-radius:50%;border-color:#1c1a19}
/* A chip is never squeezed: the row does not wrap, so a chip that gave way lost its insides — the
   sky went first and the degrees ran out over the next chip. And on a narrow phone a half-width
   cell leaves the weather to the post: the sky, the faces and the thoughts with a three-figure
   count are 155px and more, a cell has 130 of room at 320 and 150 at 360, and 165 from 390 up. */
.tile .polaroid>.meta>*,.tile .t-place>.meta>*,.tile .t-sticker>.meta>*{flex:none}
@media (max-width:374px){
  .mosaic>[data-shape^=w1] .polaroid>.meta .wx,.mosaic>[data-shape^=w1] .t-place>.meta .wx,
  .mosaic>[data-shape^=w1] .t-sticker>.meta .wx{display:none}
}

/* A place: the map to the edge of its cell, cut round its pin wherever it is cut — the pin and the
   spot are both at 57% across and 43% down, so holding the picture there keeps one on the other. */
.tile .t-place{position:relative;height:100%}
.tile .t-place .mapcard{max-width:none;width:100%;height:100%;padding:0;border:0;box-shadow:none;background:var(--surface-1)}
.tile .t-place .mapcard .map{aspect-ratio:auto;height:100%}
.tile[data-shape=full] .t-place .mapcard .map{aspect-ratio:2/1;height:auto}
.tile .t-place .mapcard .map img{object-position:57% 43%}
.tile .t-place .mapcard .name{left:8px;right:auto;bottom:38px;max-width:calc(100% - 16px);padding:4px 9px;border-radius:10px;
  background:rgba(28,26,25,.72);color:#fff;font-size:10px}
/* The pin, round: a head with a punched centre and a narrower point under it, its tip still on the
   spot (the head sits 0.35 of a pin above it now, where the square one sat 0.5). */
.tile .t-place .mapcard .pin{border-radius:50%;transform:translate(-50%,calc(-100% - var(--pin) * .35))}
.tile .t-place .mapcard .pin b{border-radius:50%}
.tile .t-place .mapcard .pin::after{top:calc(100% - var(--pin) * .2);border-left-width:calc(var(--pin) * .3);
  border-right-width:calc(var(--pin) * .3);border-top-width:calc(var(--pin) * .55)}
/* A covered picture's label is a chip like every other on a tile. The coded one is on the deeper
   accent in both themes: white 11px words on the bright one are 4.2:1, on this 5.1. (The Post's
   large label is the Post's.) */
.tile .covermark{border-radius:10px}
.tile .covermark.locked{background:#d42a10}
/* A sticker: the cut-out in the middle of its cell. */
.tile .t-sticker{position:relative;height:100%;display:grid;place-items:center;padding:12px 12px 34px;background:var(--surface-1)}
.tile[data-shape=full] .t-sticker{height:auto;min-height:148px}
.tile .t-sticker .sticker{max-width:none;width:auto;height:100%;max-height:96px}

/* ─── a card of words ────────────────────────────────────────────────────────
   Everything that is not a picture: who and when along the top, the thing itself, and what has
   been said about it along the foot — a chip per face, the plus, and the thoughts at the far end. */
.tile .paperc{display:flex;flex-direction:column;align-items:stretch;gap:10px;min-width:0;width:100%;padding:12px;background:var(--surface-1);color:var(--text)}
.arow{display:flex;align-items:center;gap:8px;min-width:0}
.arow .nm{flex:1;min-width:0;font-family:var(--font-heading);font-weight:800;font-size:13px;line-height:1.2;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.arow .tm{flex:none;margin-left:auto;font-size:11px;line-height:1.2;color:var(--muted);font-variant-numeric:tabular-nums}
.arow.bare .tm{margin-left:0}
.tile .t-text .strip{display:block;padding:0;background:none;box-shadow:none;color:var(--text);text-transform:none;
  font-family:var(--font-heading);font-weight:800;font-size:17px;line-height:1.3;letter-spacing:-.01em;text-wrap:pretty;overflow-wrap:anywhere}
.tile .t-quote .block{border-left:3px solid var(--color-accent);padding:2px 0 3px 12px;color:var(--text)}
.tile .t-quote .qbody{font-family:var(--font-heading);font-weight:800;font-size:19px;line-height:1.2;letter-spacing:-.02em;text-wrap:pretty;overflow-wrap:anywhere}
.tile .t-quote .qsrc{margin-top:8px;font-size:10px;letter-spacing:.1em;text-transform:uppercase;font-weight:600;color:var(--muted)}
/* The foot. Generic .meta below is the reminders' and feedback's, and they keep it. */
.meta{display:flex;flex-wrap:wrap;align-items:center;gap:6px;padding:9px 0 0;font-size:10px;color:var(--jr-photo-mute)}
.meta .rxrow{flex:0 1 auto;min-width:0}
.meta .cbtn{margin-left:auto}
.meta .from{color:var(--accent-text);text-transform:uppercase;letter-spacing:.08em;font-size:8px}
.tile .paperc>.meta,.scard>.meta{display:flex;flex-wrap:wrap;align-items:center;gap:4px;margin:0;padding:0;color:var(--muted);font-size:11px}
.tile .paperc>.meta .from,.scard>.meta .from{flex-basis:100%;font-size:9px;font-weight:800;letter-spacing:.08em;color:var(--accent-text)}
.tile .paperc>.meta .rxrow,.scard>.meta .rxrow{display:flex;flex-wrap:wrap;gap:4px;margin:0;flex:0 1 auto;min-width:0}
.tile .paperc>.meta .rxtally,.scard>.meta .rxtally{height:26px;padding:0 8px;gap:4px;border:0;border-radius:13px;background:var(--surface-2);color:var(--text)}
.tile .paperc>.meta .rxtally .e,.scard>.meta .rxtally .e{font-size:13px}
.tile .paperc>.meta .rxtally b,.scard>.meta .rxtally b,.tile .paperc>.meta .cbtn b,.scard>.meta .cbtn b{font-family:var(--font-heading);font-size:11px;font-weight:800}
.tile .paperc>.meta .rxtally.mine,.scard>.meta .rxtally.mine{background:var(--accent-tint);color:var(--accent-tint-text)}
.tile .paperc>.meta .rxadd,.scard>.meta .rxadd{width:26px;height:26px;border:0;border-radius:50%;background:var(--surface-2);color:var(--text-2)}
.tile .paperc>.meta .rxadd svg,.scard>.meta .rxadd svg{width:12px;height:12px;stroke-width:2.4}
.tile .paperc>.meta .wx,.scard>.meta .wx{margin-left:auto;color:var(--muted)}
.tile .paperc>.meta .cbtn,.scard>.meta .cbtn{height:26px;min-width:26px;margin-left:auto;padding:0 8px;gap:4px;border:0;border-radius:13px;
  background:var(--surface-2);color:var(--text)}
.tile .paperc>.meta .wx~.cbtn,.scard>.meta .wx~.cbtn{margin-left:0}
.tile .paperc>.meta .cbtn:not(:has(b)),.scard>.meta .cbtn:not(:has(b)){padding:0;width:26px}
.tile .paperc>.meta .cbtn .nm,.scard>.meta .cbtn .nm{top:-2px;right:-2px;border-radius:50%;border-color:var(--surface-1)}

/* A voice note: a play button and the shape of what was said. It still plays from here. */
.t-voice{background:var(--color-surface);border:1px solid var(--color-divider);padding:8px 10px;display:flex;align-items:center;gap:10px}
.playsq{width:30px;height:30px;flex:none;background:var(--color-accent);color:var(--color-bg);display:grid;place-items:center;border:0;padding:0;cursor:pointer}
.wave{flex:1;display:flex;align-items:center;gap:2px;height:24px;min-width:0}
.wave i{flex:1;background:var(--color-text);display:block}
.wave.grey i{background:var(--color-neutral-400)}
.t-voice .r{text-align:right;font-size:10px;line-height:1.2;color:var(--color-neutral-600)}
.tile .paperc.t-voice{display:flex;flex-direction:column;align-items:stretch;gap:10px;padding:12px;border:0;background:var(--surface-1)}
.tile .t-voice .vrow{display:flex;align-items:center;gap:10px;min-width:0;padding:6px 12px 6px 6px;border-radius:var(--radius-md);background:var(--surface-2)}
.tile .t-voice .playsq{width:36px;height:36px;border-radius:50%;background:var(--accent-fill);color:var(--on-accent)}
.tile .t-voice .wave i{background:var(--text-2);border-radius:1px}
.tile .t-voice .r{font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums}
/* A link, as a link: underlined, with the way out marked. */
.tile .t-link .linkrow{display:grid;grid-template-columns:22px 1fr;column-gap:10px;align-items:center;padding:10px 12px;border:0;
  border-radius:10px;background:var(--surface-2);width:100%}
.tile .t-link .linkrow .launch{width:22px;height:22px;margin:0;border-radius:50%;background:var(--text);color:var(--page)}
.tile .t-link .linkrow .body{grid-column:2;display:block;min-width:0}
.tile .t-link .linkrow .ttl{display:block;font-family:var(--font-heading);font-weight:800;font-size:15px;letter-spacing:-.01em;color:var(--text);
  text-decoration:underline;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tile .t-link .linkrow .url{display:block;padding:3px 0 0;font-size:12px;color:var(--muted);overflow-wrap:anywhere}
/* A document: its first page, from the top, then what it is called and how big. */
.tile .t-file .pdfshot{margin:0;overflow:hidden;border:0;border-radius:10px;background:#fff}
.tile .t-file .pdfshot .media-box{max-height:240px}
.tile .t-file .filerow{border:0;border-radius:10px;background:var(--surface-2);color:var(--text);padding:10px 12px}
.tile .t-file .filerow .kind{border-radius:6px;background:var(--text);color:var(--page)}
.tile .t-file .filerow .sub{color:var(--muted)}
/* A question and a poll keep their form — who asked and how far along, the question, a line a seat
   or a box a choice — on the card rather than on a sheet of paper of their own. */
.tile .qcard{background:none;border:0;box-shadow:none;color:var(--text)}
.tile .qbar{background:none;color:var(--muted);padding:0 0 8px}
.tile .qbar .from{font-size:10px;letter-spacing:.1em;color:var(--accent-text)}
.tile .qbar .tally{font-size:10px;letter-spacing:.1em;opacity:1}
.tile .qbody{padding:0}
.tile .qbody .q{font-size:17px;line-height:1.3}
.tile .qline .rule{border-bottom-color:var(--rule)}
.tile .qline .ans{color:var(--accent-text)}
.tile .qline .turn{color:var(--accent-text)}
.tile .qline .who,.tile .qmore{color:var(--muted)}
.tile .pchoice{border-bottom-color:var(--rule)}
.tile .pchoice .box{border-color:var(--muted);border-radius:4px;background:none}
.tile .pchoice.mine .box{background:var(--color-accent);border-color:var(--color-accent)}
.tile .pchoice .n,.tile .pchoice.mine .lbl{color:var(--accent-text)}
.tile .pchoice .pbar{border-radius:2px}
/* A game: the scoreboard, on the card. */
.tile .t-game .gametile{background:none;border:0;padding:0;color:var(--text)}
.tile .t-game .gt-kick{color:var(--muted)}
/* A milestone: the one thing on a spread meant to be seen across the room, on a tint of its own.
   Straight now, like everything else. */
.tile .t-milestone .mstone{max-width:none;width:100%;border:0;border-radius:10px;background:var(--accent-tint);color:var(--text);
  box-shadow:none;padding:12px 14px}
.tile .t-milestone .mstone .mk{color:var(--accent-tint-text)}
.tile .t-milestone .mstone .mn{color:var(--text-2)}
/* A letter: an envelope with a seal until its day, then the words. */
.tile .t-letter .envelope{max-width:none;width:100%;aspect-ratio:auto;min-height:104px;border:0;border-radius:10px;background:var(--surface-2);
  color:var(--text);box-shadow:none;padding:10px 12px}
.tile .t-letter .envelope .flap{background:linear-gradient(to bottom left,transparent 49.5%,var(--surface-3) 49.5%,var(--surface-3) 51.5%,transparent 51.5%) left top/50% 100% no-repeat,
  linear-gradient(to bottom right,transparent 49.5%,var(--surface-3) 49.5%,var(--surface-3) 51.5%,transparent 51.5%) right top/50% 100% no-repeat}
.tile .t-letter .envelope .seal{border-radius:50%;box-shadow:0 0 0 2px var(--surface-2)}
.tile .t-letter .envelope .lk{color:var(--muted)}
.tile .t-letter.ready .envelope{box-shadow:inset 0 0 0 2px var(--color-accent)}
.tile .t-letter.ready .envelope .lo{color:var(--accent-text)}
.tile .t-letter .letter{border:0;border-left:3px solid var(--color-accent);background:none;box-shadow:none;color:var(--text);padding:2px 0 2px 12px}
.tile .t-letter .letter .lk,.tile .t-letter .lread span{color:var(--muted)}
.tile .t-letter .lread{border-top-color:var(--rule)}

/* ─── a card of scales ───────────────────────────────────────────────────────
   Half the width in the mosaic beside another, the whole of it alone and in the feed. A label and
   the figure on one line, and under them a bar of ten — the fill is what was given; a number has no
   ten to be out of, so it has no bar, only its figure and unit. */
.scard{display:flex;flex-direction:column;gap:10px;min-width:0;padding:12px;border-radius:var(--radius-md);background:var(--surface-1);color:var(--text);cursor:pointer}
.scard .srows{display:flex;flex-direction:column;gap:10px}
.scard .srow{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"nm v" "tr tr";align-items:baseline;column-gap:8px;row-gap:5px;padding:0;border:0}
/* Two lines before an ellipsis: a half card at 320 has 90px for the label, and "Vermisse dich" in
   these capitals is 96. */
.scard .srow .nm{grid-area:nm;min-width:0;font-size:10px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--text-2);
  overflow:hidden;overflow-wrap:anywhere;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}
.scard .srow .v{grid-area:v;width:auto;text-align:right;font-family:var(--font-heading);font-weight:800;font-size:16px;line-height:1;
  font-variant-numeric:tabular-nums;color:var(--text)}
.scard .srow .v i{font-style:normal;font-size:10px;font-weight:600;color:var(--muted);margin-left:3px}
.scard .srow .track{grid-area:tr;position:relative;display:block;width:auto;height:6px;border-radius:3px;background:var(--surface-2);overflow:hidden}
.scard .srow .track i{position:absolute;display:block;border-radius:3px;background:var(--color-accent)}
.scard .snote{padding:0;font-size:13px;line-height:1.4;color:var(--text)}

/* wall */
.wall{padding:0 14px 24px}
.wall .mh{display:flex;justify-content:space-between;align-items:baseline;padding:14px 4px 10px;border:0;margin:0}
.wall .mh b{font-family:var(--font-heading);font-weight:800;font-size:18px;letter-spacing:-.02em}
.wall .mh span{font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.wall .days{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin-bottom:8px}
.daycard{cursor:pointer;display:flex;flex-direction:column;gap:6px;min-width:0}
.daycard .box{aspect-ratio:3/4;background:var(--surface-1);border-radius:var(--radius-md);padding:4px;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);grid-auto-rows:minmax(0,1fr);gap:3px;overflow:hidden}
.daycard .box>*{border-radius:10px}
.daycard .th-photo{position:relative;background:var(--surface-2);min-height:0;overflow:hidden}
.daycard .th-photo img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.daycard .th-text{background:var(--surface-2);color:var(--text);font-family:var(--font-heading);font-weight:800;font-size:7px;line-height:1.3;padding:4px;overflow:hidden;min-height:0;overflow-wrap:anywhere}
.daycard .th-quote{background:var(--surface-2);color:var(--text);box-shadow:inset 2px 0 0 var(--color-accent);font-family:var(--font-heading);font-weight:800;font-size:8px;line-height:1.15;padding:4px 4px 4px 6px;overflow:hidden;min-height:0}
.daycard .th-emo{display:grid;place-items:center;min-height:0;min-width:0;container-type:size;background:var(--surface-2)}
.daycard .th-emo span{border-radius:8px;background:var(--accent-tint);color:var(--accent-tint-text);padding:3px 6px;font-family:var(--font-heading);font-weight:800;font-size:11px;line-height:1}
.daycard .th-other{background:var(--surface-2);min-height:0}
.daycard .foot{display:flex;justify-content:space-between;padding:0 2px;font-size:11px}
.daycard .foot b{font-weight:800}
.daycard .foot span{color:var(--muted);font-variant-numeric:tabular-nums}

/* emotions */
.emo{padding:0 14px 24px}
.emo .legend{display:flex;flex-wrap:wrap;align-items:center;gap:6px 14px;padding:12px 4px 12px;border:0;font-size:10px;font-weight:800;
  letter-spacing:.1em;text-transform:uppercase;color:var(--text-2)}
.emo .legend .muted{color:var(--muted);font-weight:600}
.emo .legend .sw{display:flex;align-items:center;gap:6px}
.emo .legend .sw i{width:10px;height:10px;border-radius:50%;display:block}
.emo .scale{margin-bottom:8px;padding:12px 14px 14px;border:0;border-radius:var(--radius-md);background:var(--surface-1)}
.emo .scale .hd{display:flex;justify-content:space-between;align-items:baseline;gap:10px;margin-bottom:10px}
.emo .scale .hd b{font-family:var(--font-heading);font-weight:800;font-size:15px}
.emo .scale .hd .vals{display:flex;gap:10px;font-family:var(--font-heading);font-size:14px;font-weight:800;font-variant-numeric:tabular-nums}
/* Each figure in ink, after a dot of its person's line colour: the colour says whose it is, as the
   legend's dots do, and the figure stays readable on the card (a red figure was 3.3:1 on it). */
.emo .scale .hd .vals span{display:inline-flex;align-items:center;gap:5px;color:var(--text)}
.emo .scale .hd .vals span::before{content:'';flex:none;width:8px;height:8px;border-radius:50%;background:var(--c)}
.emo svg{display:block;overflow:visible;width:100%;height:60px}

/* ─── entry detail ──────────────────────────────────────────────────────── */
/* The journal over the day it was posted: 14/800 and 12, the design's bar on a post. */
.detail .who{flex:1;font-size:12px;line-height:1.3;min-width:0}
.detail .who b{display:block;font-family:var(--font-heading);font-weight:800;font-size:14px;line-height:1.25;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.detail .who span{color:var(--muted);display:block;margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Everything that is not a picture is a card of its own under the author's line: the surface, the
   corners, the words in the design's type. Same as its tile on the spread, a size up. */
.detail .hero-text{margin:4px 14px 0;padding:16px;border-radius:var(--radius-md);background:var(--surface-1)}
.detail .hero-text .strip{display:block;padding:0;background:none;box-shadow:none;color:var(--text);text-transform:none;
  font-family:var(--font-heading);font-weight:800;font-size:19px;line-height:1.3;letter-spacing:-.01em;text-wrap:pretty;overflow-wrap:anywhere}
/* A quote is the hero: its own text, at display size, with the accent rule down its left edge that
   its tile on the spread has. */
.detail .hero-quote{margin:12px 18px 4px;border-left:3px solid var(--color-accent);padding:2px 0 3px 16px;color:var(--text)}
.detail .hero-quote .qbody{font-family:var(--font-heading);font-weight:800;font-size:26px;line-height:1.16;letter-spacing:-.02em;text-wrap:pretty;overflow-wrap:anywhere}
.detail .hero-quote .qsrc{margin-top:11px;font-size:10px;letter-spacing:.1em;text-transform:uppercase;font-weight:600;color:var(--muted)}
.detail .hero-emo{padding:24px 16px 8px;display:flex;align-items:center;gap:16px}
.detail .hero-emo .stamp{padding:8px 13px}
.detail .hero-emo .stamp .lbl{font-size:10px}
.detail .hero-emo .stamp .num{font-size:26px}
.detail .hero-emo .stamp .of{font-size:10px}
.detail .bar6{flex:1;height:6px;background:var(--color-neutral-300);position:relative}
.detail .bar6 i{position:absolute;left:0;top:0;bottom:0;background:var(--color-accent)}
/* Several scales logged at once are one post, so the post shows all of them — on one card, the
   card of scales a size up: a name in capitals with its figure on the right, and a bar of ten
   under them, rounded at both ends. A number has no ten to be out of, so it has no bar. */
.detail .hero-stack{margin:4px 14px 0;padding:16px;border-radius:var(--radius-md);background:var(--surface-1);
  display:flex;flex-direction:column;gap:16px}
.detail .hero-stack .hero-emo{padding:0;display:flex;flex-direction:column;align-items:stretch;gap:8px}
.detail .hero-stack .stamp{display:flex;align-items:baseline;gap:6px;padding:0;border:0;background:none;color:var(--text);white-space:normal}
.detail .hero-stack .stamp .lbl{flex:1;min-width:0;font-size:11px;font-weight:800;letter-spacing:.1em;color:var(--text-2);overflow-wrap:anywhere}
.detail .hero-stack .stamp .num{flex:none;font-size:24px;font-weight:800;letter-spacing:-.02em;color:var(--text);font-variant-numeric:tabular-nums}
.detail .hero-stack .stamp .of{flex:none;font-size:11px;font-weight:600;color:var(--muted)}
.detail .hero-stack .bar6{flex:none;height:8px;border-radius:4px;background:var(--surface-2);overflow:hidden}
.detail .hero-stack .bar6 i{border-radius:4px}
.detail .hero-stack .emonote{color:var(--text);font-size:15px;line-height:1.45;margin:0}
.detail .hero-other{margin:4px 14px 0;padding:16px;border-radius:var(--radius-md);background:var(--surface-1);
  font-family:var(--font-heading);font-weight:800;font-size:20px;overflow-wrap:anywhere}
.detail .hero-other a{color:inherit;text-decoration:none}
.detail .hero-voice{padding:4px 14px 0}
.detail .hero-voice .t-voice{border:0;border-radius:var(--radius-md);background:var(--surface-1);padding:10px 14px 10px 10px;gap:12px}
.detail .hero-voice .playsq{width:40px;height:40px;border-radius:50%;background:var(--accent-fill);color:var(--on-accent)}
.detail .hero-voice .wave i{background:var(--text-2);border-radius:1px}
.detail .hero-voice .r{font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums}
.detail .hero-place{padding:4px 14px 0;display:flex;flex-direction:column;align-items:flex-start;gap:10px}
.detail .hero-place .maplink{display:block;width:100%;text-decoration:none;color:inherit}
/* The map, as its tile draws it: cut to the corners with nothing round it, the name on a dark chip
   and the pin round with its tip still on the spot. */
.detail .hero-place .mapcard{max-width:none;width:100%;padding:0;border:0;border-radius:var(--radius-md);overflow:hidden;
  box-shadow:none;background:var(--surface-1)}
.detail .hero-place .mapcard .name{left:10px;right:auto;bottom:10px;max-width:calc(100% - 20px);padding:5px 10px;border-radius:10px;
  background:rgba(28,26,25,.72);color:#fff}
.detail .hero-place .mapcard .credit{border-radius:4px}
.detail .hero-place .mapcard .pin{border-radius:50%;transform:translate(-50%,calc(-100% - var(--pin) * .35))}
.detail .hero-place .mapcard .pin b{border-radius:50%}
.detail .hero-place .mapcard .pin::after{top:calc(100% - var(--pin) * .2);border-left-width:calc(var(--pin) * .3);
  border-right-width:calc(var(--pin) * .3);border-top-width:calc(var(--pin) * .55)}
/* "Open in Maps": a pill on the surface, the app's own button rather than the blue link, because
   it leaves for another app rather than for a web page. */
.detail .openmaps{display:inline-flex;align-items:center;gap:6px;min-height:34px;padding:0 13px;border-radius:17px;
  background:var(--surface-1);font-size:10px;font-weight:800;letter-spacing:.1em;
  text-transform:uppercase;color:var(--text-2);text-decoration:none}
/* Under the picture or the card: the design's 12 and 14, the caption a step in from the row. */
.detail .body{padding:12px 14px 0}
.detail .body p{font-size:15px;line-height:1.45;margin:0 4px 12px;overflow-wrap:anywhere;color:var(--text)}
.detail .act{min-height:56px;min-width:0;display:flex;align-items:center;gap:8px;padding:0 12px;
  border:0;border-left:1px solid var(--color-divider);background:none;color:var(--color-text);
  font-family:var(--font-heading);font-weight:600;font-size:12px;text-align:left;cursor:pointer;
  -webkit-tap-highlight-color:transparent}
.detail .act:first-child{border-left:0}
.detail .act svg{flex:none}
.detail .act span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* A third of a narrow phone is not much room, and the German labels are the longest of the three
   languages. Tighten rather than let a label be cut in half. */
@media (max-width:360px){.detail .act{padding:0 8px;gap:6px}}
.detail .replies{padding:14px 16px 20px}
.detail .replies .kicker{margin:0 0 10px}
.detail .reply{display:flex;gap:10px;padding:10px 0;border-top:1px solid var(--color-divider)}
.detail .reply .c{flex:1;min-width:0}
.detail .reply .m{font-size:11px;color:var(--color-neutral-600);display:flex;justify-content:space-between}
.detail .reply .x{font-size:14px;line-height:1.4;overflow-wrap:anywhere}
/* A GIF comment, under the name line: its own shape, sized before it loads (width and height are
   written on it), never wider than the column, rounded like the cards round it. */
.detail .reply .rgif{display:block;flex:none;max-width:100%;height:auto;margin-top:4px;border-radius:var(--radius-md);object-fit:cover;
  background:var(--surface-1);-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
/* ─── reactions ──────────────────────────────────────────────────────────── */
/* Three scales of one idea: a control with an edge, divided into equal cells. What it replaced was
   a floating box of loose emoji with nothing to align to, and a single outlined box that read as an
   empty checkbox rather than as somebody's reaction. */

/* The picker. Seven equal cells, filled and rounded, a little apart — the row of faces above the
   field, at the size of a thought. No box round them and no shadow. It sits flush with the message
   text because it belongs to that message, and the text's own left edge is the only thing on the
   row worth aligning to. */
.rxstrip{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;margin-top:8px;border:0;background:none}
.rxcell{height:46px;display:grid;place-items:center;padding:0;border:0;border-radius:12px;
  background:var(--surface-1);color:var(--text);font:inherit;font-size:21px;line-height:1;cursor:pointer;
  -webkit-tap-highlight-color:transparent}
.rxcell:hover,.rxcell:active{background:var(--surface-2)}
/* The one you have already used stays tinted, so your own reaction is visible here as well as in
   the tally — without having to open the tally to find it. */
.rxcell.on{background:var(--accent-tint)}
/* The plus is the one cell that opens something instead of committing a reaction, so it is drawn as
   a glyph rather than as an emoji. */
.rxcell.more{color:var(--text)}

/* The tally. A chip per emoji, always carrying its number — one is a count too. Yours is filled
   ink; everybody else's is an outline. That single difference is the whole state. */
.rxrow{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-top:6px}
.rxtally{display:inline-flex;align-items:center;gap:5px;height:30px;padding:0 8px;cursor:pointer;
  border:1px solid var(--color-divider);background:none;color:var(--color-text);font:inherit;
  line-height:1;-webkit-tap-highlight-color:transparent}
.rxtally .e{font-size:14px;line-height:1}
.rxtally b{font-family:var(--font-heading);font-weight:700;font-size:11px;font-variant-numeric:tabular-nums}
.rxtally.mine{border-color:var(--color-text);background:var(--color-text);color:var(--color-bg)}
/* Always there, so reacting never depends on remembering that a message can be double-tapped. */
.rxadd{width:30px;height:30px;flex:none;display:grid;place-items:center;cursor:pointer;
  border:1px solid var(--color-divider);background:none;color:var(--color-neutral-700);
  -webkit-tap-highlight-color:transparent}
.rxadd:hover{color:var(--color-text);border-color:var(--color-text)}
/* On the opened post the same chips sit a size up — there is a whole screen here, not a tile: the
   design's pill, 38 tall beside Like and Nope, and yours on the accent's tint. */
.rxrow.big{margin-top:0;gap:6px}
.rxrow.big .rxtally{height:38px;padding:0 13px;gap:6px;border:0;border-radius:19px;background:var(--surface-1);color:var(--text)}
.rxrow.big .rxtally.mine{background:var(--accent-tint);color:var(--text)}
.rxrow.big .rxtally .e{font-size:16px}
.rxrow.big .rxtally b{font-family:var(--font-heading);font-size:13px;font-weight:800}
.rxrow.big .rxadd{width:38px;height:38px;border:0;border-radius:50%;background:var(--surface-1)}
/* On a tile the chips are the mosaic's own: see "a card of words" and the chips at the foot of a
   picture, under "the spread: a mosaic". */

/* Any emoji: the same divided control at grid scale, in a sheet rather than a screen. */
/* No rule across the top since 9.7.5. The comment popup gave its up for the rounded top and the
   grabber in 9.7.4 and no other sheet had one; this one kept a 2px line in the text colour, which
   drew a rim along its rounded top — dark in the light theme, light in the dark. */
/* The sheet's own colour is the bottom sheets' (see .sheet-backdrop>.sheet). Its head: the name in
   capitals and a round close; under it a search pill; then the sections, seven to a row in rounded
   cells with nothing drawn between them. */
.emojisheet{max-height:78%;display:flex;flex-direction:column}
.eshd{flex:none;display:flex;align-items:center;justify-content:space-between;gap:10px;padding:21px 14px 10px 18px}
.eshd .k{font-family:var(--font-heading);font-size:11px;letter-spacing:.1em;text-transform:uppercase;font-weight:800;color:var(--text)}
.eshd .x{width:34px;height:34px;flex:none;display:grid;place-items:center;padding:0;border:0;border-radius:50%;
  background:var(--surface-1);color:var(--text);cursor:pointer}
.esearch{flex:none;position:relative;margin:0 14px}
.esearch .input{display:block;width:100%;height:44px;min-height:44px;padding:0 16px 0 41px;border-radius:22px;
  -webkit-appearance:none;appearance:none}
.esearch svg{position:absolute;left:16px;top:50%;margin-top:-7.5px;color:var(--muted);pointer-events:none}
.esbody{flex:1;min-height:0;overflow:auto;overscroll-behavior:contain;padding:0 12px 16px}
.eslbl{margin:0;padding:14px 6px 6px;font-size:10px;letter-spacing:.1em;text-transform:uppercase;font-weight:600;color:var(--muted)}
.esgrid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;background:none;border:0}
.escell{height:44px;display:grid;place-items:center;padding:0;border:0;border-radius:12px;background:none;color:var(--text);
  font:inherit;font-size:24px;line-height:1;cursor:pointer;-webkit-tap-highlight-color:transparent}
.escell:hover,.escell:active{background:var(--surface-1)}
.escell.empty{pointer-events:none}
.esnone{padding:20px 6px;font-size:13px;color:var(--muted)}
/* Who said what (drop 7): the emoji sheet's head, then — on a thought's — the quick row, then one row
   a person: their face, their name, a small You on yours, and what they put at the far end. The
   sheet itself scrolls, as the journal's settings do, so a long list pulls down from its top. */
.whosheet{padding-bottom:calc(10px + env(safe-area-inset-bottom))}
.whosheet .rxstrip{margin:2px 14px 8px}
.wholist{padding:2px 0 6px}
.whorow{display:flex;align-items:center;gap:12px;min-height:52px;padding:0 18px}
.whorow .n{min-width:0;font-family:var(--font-heading);font-weight:800;font-size:14px;color:var(--text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.whorow .you{flex:none;font-style:normal;font-size:10px;letter-spacing:.1em;text-transform:uppercase;font-weight:600;color:var(--muted)}
.whorow .e{flex:none;margin-left:auto;font-size:20px;line-height:1}
.wholist .none{padding:14px 18px;font-size:13px;color:var(--muted)}
/* The GIF comment's picker: the emoji sheet's head and search pill (.eshd, .esearch), then a grid
   three across that scrolls on its own, and Giphy's name at the foot. A fixed height rather than a
   cap, so the sheet does not grow under the finger as the answers arrive. .chat .ggrid is the
   chat tray's and is scoped to it; these are scoped to the sheet. */
.gifsheet{height:78%;display:flex;flex-direction:column;overflow:hidden}
.gifsheet .ggrid{flex:1;min-height:0;overflow:auto;overscroll-behavior:contain;display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));grid-auto-rows:max-content;gap:6px;align-content:start;padding:12px 14px 6px}
.gifsheet .gg{aspect-ratio:1;border:0;border-radius:12px;background:var(--surface-1);cursor:pointer;padding:0;overflow:hidden}
.gifsheet .gg img{width:100%;height:100%;object-fit:cover;display:block}
.gifsheet .gnone{grid-column:1/-1;padding:18px 6px;text-align:center;font-size:13px;color:var(--muted)}
.gifsheet .gerr{flex:none;padding:12px 18px 0}
/* Powered by GIPHY: Giphy's terms ask for it wherever their API is used. Small, in the app's type. */
.gifsheet .gmark,.chat .gmark{flex:none;align-self:flex-end;font-family:var(--font-heading);font-size:10px;font-weight:800;
  letter-spacing:.06em;color:var(--muted);line-height:1}
.gifsheet .gmark{padding:4px 18px 12px}
/* The thought being written: one pill — your face, the words, and a round red send — over the
   page, the way the design draws it. Still the same element under the same rules: a box that is
   not a form control (see ReplyBar), Enter to send, the button beside it to tap. */
.detail .composer{display:flex;padding:8px 12px;padding-bottom:calc(16px + env(safe-area-inset-bottom));border-top:0;flex:none}
/* The same 16 with the keyboard up, less only the safe area the keyboard covers: a padding that
   changed with the keyboard would move the foot of the thread by the difference (small3). */
.kb .detail .composer{padding-bottom:16px}
/* Not a textarea — see ReplyBar. Which means the things a textarea did for nothing are here: it
   grows by itself up to 120px and then scrolls, it breaks long words rather than running off the
   edge, and the placeholder is drawn rather than given. The pill grows with it, and the face and
   the send stay on the last line. */
.detail .composer .input{min-height:48px;flex:1;min-width:0;max-height:120px;
  overflow-y:auto;padding:13px 4px 14px;border:0;border-radius:0;background:none;
  color:var(--text);font:inherit;font-size:15px;line-height:1.4;
  white-space:pre-wrap;overflow-wrap:anywhere;-webkit-user-select:text;user-select:text;
  box-sizing:border-box;text-align:left;cursor:text;outline:none}
.detail .composer .input:focus,.detail .composer .input:focus-visible{outline:none}
.detail .composer .input:empty::before{content:attr(data-ph);color:var(--placeholder);
  pointer-events:none;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* The face goes at the bottom of the line, so a thought that has grown to three lines still has it
   beside the line being typed rather than floating against the top of the box. */
.detail .composer .row .avatar{flex:none;align-self:flex-end;width:38px;height:38px;margin-bottom:5px;font-size:16px}
/* Hit at 44, drawn at 40: a 2px clear edge with the fill clipped inside it, and the edge taken back
   out of the row by the margins, so the disc sits where a 40px button sat. */
.detail .composer .psend{flex:none;align-self:flex-end;width:44px;height:44px;min-height:44px;margin:0 -2px 2px;padding:0;
  border:2px solid transparent;border-radius:50%;display:grid;place-items:center;background:var(--accent-fill);
  background-clip:padding-box;color:var(--on-accent)}
.detail .composer .psend:disabled{background-color:var(--surface-2);color:var(--disabled)}
/* GIF, in the pill beside the send: hit at 44 like the send, drawn as the word in a small rounded
   frame, the way Instagram's comment bar draws it. In the quiet ink, because the send is the loud one.
   The two 44s meet edge to edge: the right margin and the send's own -2px take back the row's 6px gap
   exactly, so a tap between them is never given to the other one. */
.detail .composer .pgif{flex:none;align-self:flex-end;width:44px;height:44px;min-height:44px;margin:0 -4px 2px -6px;padding:0;
  border:0;background:none;display:grid;place-items:center;color:var(--text-2);cursor:pointer;-webkit-tap-highlight-color:transparent}
.detail .composer .pgif span{display:block;padding:4px 5px 3px;border:1.5px solid currentColor;border-radius:7px;
  font-family:var(--font-heading);font-size:10px;font-weight:800;line-height:1;letter-spacing:.04em}

/* ─── composer ──────────────────────────────────────────────────────────── */
.compose .hdr{padding:20px 16px 10px}

.editor{flex:1;padding:24px 20px 24px}
/* The photo editor holds itself to the screen.
   It used to give the picture 46vh of a scrolling column, so you added a photo and then had to
   scroll past it to say anything about it — on a short phone the caption was never in sight at the
   same time as the thing it was about. The column is a flex stack now: everything that has to be
   there keeps its height, and the picture takes exactly what is left. It cannot overflow, and on a
   tall phone it does not waste the room either. The cap stops it dominating a tablet. */
.editor.fit{display:flex;flex-direction:column;overflow-y:auto;min-height:0}
.editor.fit > div{flex:1;min-height:0;display:flex;flex-direction:column}
/* The floor matters as much as the cap. Without it a short phone squeezed the picture to 85px
   inside a polaroid that kept its own size, which looked broken; below this the zoom row — the last
   thing anyone touches — goes under the fold instead, and the caption stays where it belongs, right
   under the photo. */
.editor.fit .framebox{flex:1;min-height:150px;width:auto;max-width:100%;max-height:46vh;margin:0 auto}
/* On a short screen the picture gives back some of what it is taking, for the same reason the
   preview does: the caption, the tools on the shot and the cover switch are all things to reach,
   and the photograph is not. This is the rule that actually caps a framed shot — `.shotrow .shot`
   below sets 44vh and loses to it on specificity, which is why the picture stayed its own size
   when that one was told to be smaller. */
@media (max-height:780px){
  /* The picture of the post under ON THE SPREAD is the one part of an editor that is neither
     something to read nor something to tap, so on a short screen it is the part that gives. */
  .editor .k.onspread,
  .editor .k.onspread + *{display:none}
  .editor.fit .framebox{max-height:30vh;min-height:0}
}
/* On a short screen the sentence under the zoom slider is the first thing to go: the slider says
   what it does. */
.editor .ta{font-size:16px;line-height:1.45;min-height:92px;padding:13px}
/* Words: the box the design draws (120 of room and its padding), the line under it a step away. */
.cshell[data-kind="text"] .editor .ta{min-height:148px}
.compose .mnote{margin-top:10px;font-size:12px;line-height:1.4;color:var(--muted)}
/* The names offered after an @, as filled pills rather than ink boxes. */
.compose .mentionbar button{border:0;border-radius:18px;background:var(--surface-1);color:var(--text);font-weight:800;padding:0 12px 0 6px}
.editor .k{margin-top:22px;font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.preview-strip{margin-top:12px;display:inline-block;max-width:100%;background:var(--color-text);color:var(--color-bg);font-family:var(--font-heading);font-weight:600;font-size:12px;letter-spacing:.1em;text-transform:uppercase;padding:8px 11px;line-height:1.4;box-shadow:var(--shadow-sm);transform:rotate(-1.5deg);overflow-wrap:anywhere}
/* The quote as the spread draws it: a card on the surface, straight, the words beside a 3px accent
   rule (drawn, because a border on a box with corners would bend round them). */
.preview-quote{position:relative;margin-top:12px;padding:14px 12px 15px 27px;border-radius:var(--radius-md);background:var(--surface-1);color:var(--text)}
.preview-quote::before{content:'';position:absolute;left:12px;top:16px;bottom:17px;width:3px;background:var(--color-accent)}
.preview-quote .qbody{font-family:var(--font-heading);font-weight:800;font-size:19px;line-height:1.2;letter-spacing:-.02em;text-wrap:pretty;overflow-wrap:anywhere}
.preview-quote .qsrc{margin-top:8px;font-size:10px;letter-spacing:.1em;text-transform:uppercase;font-weight:600;color:var(--muted)}
/* Two columns: every scale down the left, the value at display size on the right. */
/* Scale chips: one wrapping row instead of a scrolling stack, each 44px, each carrying its own
   figure once it is logged. Because the chip shows the value, the editor needs no list of its own
   — the tray at the bottom of Add is the only one. */
.scalechips{display:flex;flex-wrap:wrap;gap:8px}
.schip{display:inline-flex;align-items:center;gap:8px;min-height:44px;padding:0 12px;cursor:pointer;
  border:1px solid var(--color-divider);background:none;color:var(--color-text);font:inherit;font-size:13px;
  font-weight:600;-webkit-tap-highlight-color:transparent}
.schip .nm{white-space:nowrap}
.schip b{font-family:var(--font-heading);font-weight:800;font-size:15px;letter-spacing:-.02em}
.schip.on{background:var(--color-text);color:var(--color-bg);border-color:var(--color-text)}

/* The value, on the grid rather than floating: ink, left-aligned, on a 2px rule, with the
   handwritten word at the other end of the same baseline. */
.emoval{display:flex;align-items:baseline;gap:9px;margin-top:22px;padding-bottom:10px;border-bottom:2px solid var(--color-text)}
.emoval .num{font-family:var(--font-heading);font-weight:800;font-size:76px;line-height:.82;letter-spacing:-.05em;color:var(--color-text)}
.emoval .of{font-size:13px;font-weight:600;color:var(--color-neutral-600)}
.emoval .numin{flex:1;min-width:0;border:0;background:none;padding:0;outline:none;color:var(--color-text);
  font-family:var(--font-heading);font-weight:800;font-size:56px;line-height:1;letter-spacing:-.04em;
  -webkit-appearance:none}
.emoval .word{margin-left:auto;font-size:30px;line-height:1;color:var(--color-neutral-700)}
/* Feeling · Number in the softer rhythm, which is Emotion's: what it is about, how many are set, then
   a ruled row per scale — the name over its unit on the left, the figure (or a quiet dash) on the
   right. The chips are those rows; the one you are writing into is lifted onto the surface, and
   the field under the list is the one field it always was. No steppers: there is no step. */
.numview .fhead{display:flex;align-items:baseline;gap:10px;padding:10px 0 2px;font-family:var(--font-heading);
  font-weight:600;font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.numview .fhead span{flex:1;min-width:0}
.numview .fhead b{flex:none;font-weight:800;color:var(--muted);font-variant-numeric:tabular-nums}
.numview .fhead b.some{color:var(--text)}
.numview .scalechips{display:flex;flex-direction:column;flex-wrap:nowrap;gap:0}
.numview .schip{width:100%;min-height:61px;display:flex;align-items:center;gap:12px;margin:0;padding:10px 0;border:0;
  border-radius:0;background:none;box-shadow:inset 0 -1px 0 var(--rule);color:var(--text);text-align:left;font-weight:800}
/* The lift stays inside the screen's 18px gutter's reach: 6px out from the rows' edge, not 12, so
   its fill runs from 12 to 348 on a 360 screen rather than nearly to the glass. */
.numview .schip.on{background:var(--surface-1);border-radius:14px;box-shadow:none;margin:0 -6px;padding:10px 6px;width:auto}
.numview .schip:has(+ .schip.on){box-shadow:none}
.numview .schip .nm{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px;white-space:normal;
  font-family:var(--font-heading);font-weight:800;font-size:15px;line-height:1.2}
.numview .schip .u{font-style:normal;font-family:var(--font-body);font-weight:400;font-size:12px;color:var(--muted)}
.numview .schip .sep{display:none}
.numview .schip b{flex:none;font-family:var(--font-heading);font-weight:800;font-size:20px;line-height:1;letter-spacing:0;font-variant-numeric:tabular-nums}
.numview .schip:not(:has(> b))::after{content:'—';flex:none;font-family:var(--font-heading);font-weight:800;font-size:20px;line-height:1;color:var(--empty)}
.numview .emoval{display:flex;align-items:center;gap:10px;margin-top:12px;height:48px;padding:0 14px;border:0;
  border-radius:14px;background:var(--surface-1)}
.numview .emoval:focus-within{outline:2px solid var(--color-accent);outline-offset:2px}
/* 20px and not the 16 every other field is held to: that floor is iOS's zoom threshold, and the
   figure is above it, not below. */
.numview .emoval .numin{font-size:20px !important;line-height:1;letter-spacing:0;font-variant-numeric:tabular-nums}
.numview .emoval .numin::placeholder{color:var(--placeholder)}
.numview .emoval .of{font-size:12px;font-weight:400;color:var(--muted)}
.numview .note{margin-top:8px;font-size:11px;line-height:1.45;color:var(--muted)}
.numview .newscale{margin-top:14px}
.numview .newscale .input{min-height:44px}
.numview .newscale .btn{min-height:44px}
/* A short phone keeps every scale, the field and the form in sight without scrolling: the unit goes
   beside the name, the rows close up, and the sentence under the field goes — as Emotion's does
   below this height, for the same reason (see .feelview .rule). */
@media (max-height:780px){
  .numview .schip{min-height:44px;padding-block:4px}
  .numview .schip.on{padding-block:4px}
  .numview .schip .nm{flex-direction:row;align-items:baseline;gap:8px}
  .numview .note{display:none}
  .numview .newscale{margin-top:12px}
}
/* At 320 in German the name field kept only "Neue Sk" of its hint beside Einheit and Hinzufügen:
   the gaps and the side padding close a little and Add is set at 13, so the scale's own word shows. */
@media (max-width:340px){
  .numview .newscale{gap:6px}
  .numview .newscale .input{padding-left:10px;padding-right:10px}
  .numview .newscale .btn{padding-left:10px;padding-right:10px;font-size:13px}
}

/* The picture of the thing, beside the thing.
   Every editor draws what the post will look like under ON THE SPREAD, and on a screen with room
   that is the best part of the screen: you are looking at the result while you make it. On a short
   one it is the part to give up, and the only part — everything else here is something to read or
   something to tap, and a control you have to scroll to reach is a control that is not there. So
   below this height the preview goes and the editor fits, whole, on one screen. */
@media (max-height:780px){
  /* Scales carry the most furniture of the thirteen — a row of eleven cells per scale, a line to
     write, a row to add one. The sentence explaining all three is the one thing on it that is
     neither something to tap nor something to write, and every pixel it costs is a scale that
     does not fit, so on a short screen it goes the way the preview does. */
  .feelview .rule{display:none}
}
.editor .note{margin-top:11px;font-size:12px;line-height:1.45;color:var(--color-neutral-600)}

.newscale{display:flex;gap:8px;margin-top:26px}
.newscale .input{min-height:40px;flex:1}
.voicebox{display:flex;flex-direction:column;align-items:center;gap:14px;padding:22px 0 20px}
/* The record button: a rounded red square, straight, the white mic on it — and red again once
   something is recorded, since tapping it records again. Recording is the one state in ink, and
   it pulses. */
.recbtn{width:112px;height:112px;border:0;border-radius:20px;background:var(--accent-fill);color:var(--on-accent);cursor:pointer;display:grid;place-items:center;transition:background .2s}
.recbtn.done{background:var(--accent-fill)}
.recbtn.rec{background:var(--color-text);color:var(--color-bg);animation:jrPulse 1.2s ease-in-out infinite}
.voicebox .hint{font-size:13px;color:var(--muted);padding:0}
/* The player: a filled strip, the play key a rounded square on the step above it, then what was
   said — a dashed line until there is anything to draw. */
.voicestrip{background:var(--surface-1);border:0;border-radius:14px;padding:8px 14px 8px 8px;display:flex;align-items:center;gap:12px;min-height:52px}
.voicestrip .playsq{width:36px;height:36px;border-radius:10px;background:var(--surface-3);color:var(--text)}
.voicestrip .playsq:disabled{cursor:default}
.voicestrip .wave{height:28px}
.voicestrip .wave i{background:var(--text-2);border-radius:1px}
.voicestrip .wave.grey{height:0;border-top:2px dashed var(--empty)}
.voicestrip .wave.grey i{display:none}
.voicestrip .dur{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
.editor .field48{min-height:48px;font-size:16px}
/* step 2 header: the journal repeats, with a way back to step 0 */

/* ─── the tray: what is in this post ────────────────────────────────────── */
/* What the pinch has reached, in the corner of the picture it belongs to, and a tap on it puts the
   whole picture back. The only chrome the framing has, because the picture is the control. */
.framez{position:absolute;right:8px;bottom:8px;z-index:2;padding:5px 10px;cursor:pointer;
  border:0;border-radius:12px;background:rgba(28,26,25,.72);color:#fff;
  font:inherit;font-family:var(--font-heading);font-weight:800;font-size:10px;letter-spacing:.06em;text-transform:uppercase;font-variant-numeric:tabular-nums}
/* The heading and the action on one line: what is in the post on the left, the button that posts it
   on the right. It was three stacked blocks and it cost 125px of a phone. */
/* The tray wraps; it does not scroll. As a scroll row the fourth part and the Post button ran off
   the edge with no sign they were there. The remove × hangs above each chip, so a wrapped row needs
   26px of clearance above it. The action row with Post sits below, outside anything that scrolls. */
/* The words under the picture, in the tray. A thumbnail alone says a picture is in the post and
   nothing about what was written under it, which is half of what somebody made. */

/* ─── what's new ────────────────────────────────────────────────────────── */
/* The sheet's head: its kicker a small tinted pill, the round close. The drawings below are the
   app as it now is — tiles and cards with corners, chips, round marks — and nothing tilted. */
.whatsnew,.sheet.qotd{padding:21px 18px 22px}
.wn-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px}
.wn-top .k{background:var(--accent-tint);color:var(--accent-tint-text);border-radius:12px;font-family:var(--font-heading);font-weight:800;font-size:10px;letter-spacing:.1em;text-transform:uppercase;padding:5px 10px}
.wn-top .icon-btn{margin:-4px -4px -4px 0;padding:4px;background-color:var(--surface-1);background-clip:content-box;color:var(--text)}
/* Three pages stacked, the front one carrying the download mark: the feature, drawn. */
.wn-art{position:relative;height:104px;margin-bottom:18px}
.wn-art.maparound{display:grid;place-items:center}
.wn-art.maparound .mapcard{max-width:132px}
.wn-art.sevenart{display:flex;align-items:center;justify-content:center;gap:10px}
/* The three at once: a day's weather, a map with two pins, a question on its line. */
/* Pinch to zoom: a picture, the gesture, the same picture bigger. */
.wn-art.zoomart{display:flex;align-items:center;justify-content:center;gap:14px}
.wn-art.zoomart .sq{display:block;background:var(--color-accent);border-radius:12px}
.wn-art.zoomart .sq.small{width:34px;height:34px;opacity:.55}
.wn-art.zoomart .sq.big{width:86px;height:86px}
.wn-art.zoomart .spread{display:flex;align-items:center;gap:14px}
.wn-art.zoomart .spread i{display:block;width:12px;height:12px;border-radius:50%;background:var(--color-text)}
/* The sheet over the spread: the post left showing above it, the handle, and the lines of what
   people said. One picture, because the whole feature is where the thoughts arrive. */
.wn-art.csart{position:relative;width:112px;height:104px;margin:0 auto;background:var(--page);
  border-radius:var(--radius-md);overflow:hidden;box-shadow:0 0 0 1px var(--rule)}
.wn-art.csart .sq{position:absolute;left:12px;top:10px;right:12px;height:38px;background:var(--color-accent);border-radius:8px;display:block}
.wn-art.csart .sheet{position:absolute;left:0;right:0;bottom:0;height:56px;background:var(--surface-1);box-shadow:none;animation:none;
  border-radius:14px 14px 0 0;display:flex;flex-direction:column;align-items:center;gap:6px;padding:5px 12px}
.wn-art.csart .sheet .grab{display:block;width:22px;height:3px;border-radius:2px;background:var(--grab);flex:none}
.wn-art.csart .sheet .l{display:block;width:100%;height:6px;border-radius:3px;background:var(--text-2)}
.wn-art.csart .sheet .l.short{width:62%;margin-right:auto}
.wn-art.threeart{display:flex;align-items:center;justify-content:center;gap:14px}
.wn-art.threeart .d{display:flex;align-items:center;gap:4px;color:var(--color-neutral-700)}
.wn-art.threeart .d b{font-family:var(--font-heading);font-weight:800;font-size:16px}
.wn-art.threeart .m{position:relative;width:52px;height:52px;background:var(--surface-1);border-radius:12px;display:block}
.wn-art.threeart .m i{position:absolute;width:9px;height:9px;border-radius:50%;background:var(--color-accent);display:block;left:12px;top:14px;box-shadow:0 0 0 2px var(--jr-photo)}
.wn-art.threeart .m i.b{left:30px;top:30px}
.wn-art.threeart .q{width:58px;display:flex;flex-direction:column;gap:6px}
.wn-art.threeart .q i{height:9px;border-radius:5px;background:var(--color-text);display:block}
.wn-art.threeart .q b{height:2px;border-radius:1px;background:var(--muted);display:block}
/* Three journal rows with two ticked: the last step, in miniature. */
/* Four doors, one of them open: the Add screen at the size of a postage stamp. */
.wn-art.doorart{display:grid;grid-template-columns:1fr 1fr;gap:6px;align-content:center;padding:0 54px}
.wn-art.doorart .d{height:34px;border:0;border-radius:10px;background:var(--surface-1);display:block}
.wn-art.doorart .d.on{background:var(--color-accent)}
.wn-art.sevenart .mstone{max-width:150px}
.wn-art.sevenart .envelope{width:96px}

/* ─── milestone: the stamp ──────────────────────────────────────────────── */
/* The kicker with the day, the title set big, on a tint of its own with corners — the way the
   spread and the post draw it, so the composer's preview and What's new's drawing show the same
   card. The one tile allowed display type besides a quote: it is meant to be seen across the room. */
.mstone{display:flex;flex-direction:column;gap:4px;width:100%;max-width:300px;border:0;border-radius:var(--radius-md);background:var(--accent-tint);
  color:var(--text);padding:10px 12px 11px;box-shadow:none}
.mstone .mk{font-size:9px;letter-spacing:.14em;text-transform:uppercase;font-weight:600;color:var(--accent-tint-text)}
.mstone .mt{font-family:var(--font-heading);font-weight:800;font-size:22px;line-height:1.08;letter-spacing:-.02em;text-wrap:balance;overflow-wrap:anywhere}
.mstone .mn{font-size:13px;line-height:1.35;color:var(--text-2);margin-top:2px;overflow-wrap:anywhere}
.mstone.sm{max-width:140px;border-radius:var(--radius-sm);padding:6px 8px 7px;gap:2px}
.mstone.sm .mk{font-size:6px}
.mstone.sm .mt{font-size:13px}
.mstone.big{max-width:none;padding:14px 16px 15px;gap:6px}
.mstone.big .mk{font-size:10px}
.mstone.big .mt{font-size:30px}
.mstone.big .mn{font-size:15px}
.t-milestone{display:flex;flex-direction:column;align-items:flex-start;gap:6px;width:100%}
.t-milestone .meta{padding-left:4px}
/* On the post, the tile's card a size up: the tint, the corners, no frame and no shadow. */
.detail .hero-milestone{padding:4px 14px 0}
.detail .hero-milestone .mstone{border:0;border-radius:var(--radius-md);background:var(--accent-tint);color:var(--text);
  box-shadow:none;padding:16px}
.detail .hero-milestone .mstone .mk{color:var(--accent-tint-text)}
.detail .hero-milestone .mstone .mn{color:var(--text-2)}
.bigmile{margin-top:12px}
.daycard .th-mile{background:var(--accent-tint);color:var(--text);font-family:var(--font-heading);font-weight:800;text-transform:none;letter-spacing:0;font-size:7px}
/* The milestones list on the journal sheet: one row each, newest first. */
.mstones{display:flex;flex-direction:column}
.mstones .mrow{display:flex;align-items:center;gap:10px;min-height:44px;padding:6px 0;border:0;border-bottom:1px solid var(--color-divider);background:none;color:var(--color-text);font:inherit;text-align:left;cursor:pointer;width:100%}
.mstones .mrow .d{flex:none;font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--color-neutral-600);width:62px}
.mstones .mrow .n{flex:1;min-width:0;font-family:var(--font-heading);font-weight:800;font-size:14px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ─── poll: the question card with choices ───────────────────────────────── */
.pchoice{position:relative;display:flex;align-items:center;gap:9px;margin-top:9px;padding:6px 0 7px;border-bottom:1px solid var(--jr-photo-ink);min-height:30px}
.pchoice .box{flex:none;width:12px;height:12px;border:2px solid var(--jr-photo-ink);background:var(--jr-photo)}
.pchoice.mine .box{background:var(--color-accent);border-color:var(--color-accent)}
.pchoice .lbl{flex:1;min-width:0;font-size:13px;font-weight:600;line-height:1.25;overflow-wrap:anywhere}
.pchoice .n{flex:none;font-family:var(--font-heading);font-weight:800;font-size:13px;color:var(--color-accent-700);min-width:14px;text-align:right}
.pchoice .pbar{position:absolute;left:0;bottom:-1px;height:3px;background:var(--color-accent);display:block;max-width:100%}
.pchoice.mine .lbl{color:var(--color-accent-700)}
.qcard.big .pchoice{margin-top:12px;padding:9px 0 10px;min-height:40px;gap:12px;cursor:pointer}
.qcard.big .pchoice .box{width:16px;height:16px}
.qcard.big .pchoice .lbl{font-size:16px}
.qcard.big .pchoice .n{font-size:17px}
.qcard.big .pchoice .pbar{height:4px}

/* ─── number: the chip with a unit, the editor's figure, the chart ───────── */
.stamp.num .of{text-transform:none;letter-spacing:0}
.numin{width:100%;min-width:0;border:0;border-bottom:3px solid var(--color-text);background:transparent;font-family:var(--font-heading);font-weight:800;
  font-size:56px;line-height:1;letter-spacing:-.04em;color:var(--color-accent-700);padding:4px 0 6px;outline:none;-webkit-appearance:none;appearance:none}
.numin::placeholder{color:var(--color-neutral-300)}
.newscale .unitin{flex:none;width:72px}
.emo .scale .hd .unit{font-weight:400;color:var(--muted)}
.emo .range{display:flex;justify-content:space-between;font-size:10px;color:var(--muted);margin:2px 0;font-variant-numeric:tabular-nums}

/* ─── letter to the future ──────────────────────────────────────────────── */
/* The envelope: a surface with corners, a V of a flap drawn with two gradients, the seal a round
   accent mark dead centre of the flap's tip — as the spread and the post draw it, so the composer's
   preview and What's new's drawing are the same envelope. */
.envelope{position:relative;display:flex;flex-direction:column;justify-content:flex-end;gap:2px;width:100%;max-width:220px;aspect-ratio:3/2;
  background:var(--surface-2);border:0;border-radius:var(--radius-md);box-shadow:none;color:var(--text);padding:8px 10px;overflow:hidden}
/* Each half draws one diagonal as the band across a gradient — the band runs *across* the gradient's
   direction, so "to bottom left" gives the "\" of the left half and "to bottom right" the "/" of the
   right: a V from the top corners down to the seal. */
.envelope .flap{position:absolute;left:0;right:0;top:0;height:54%;
  background:linear-gradient(to bottom left,transparent 49.5%,var(--surface-3) 49.5%,var(--surface-3) 51.5%,transparent 51.5%) left top/50% 100% no-repeat,
    linear-gradient(to bottom right,transparent 49.5%,var(--surface-3) 49.5%,var(--surface-3) 51.5%,transparent 51.5%) right top/50% 100% no-repeat}
.envelope .seal{position:absolute;left:50%;top:54%;width:14px;height:14px;transform:translate(-50%,-50%);border-radius:50%;background:var(--color-accent);box-shadow:0 0 0 2px var(--surface-2)}
.envelope .lk{font-size:8px;letter-spacing:.14em;text-transform:uppercase;font-weight:600;color:var(--muted)}
.envelope .lo{font-family:var(--font-heading);font-weight:800;font-size:13px;line-height:1.1;letter-spacing:-.01em}
.envelope.sm{max-width:120px;padding:5px 7px;border-radius:var(--radius-sm)}
.envelope.sm .lk{font-size:5px}
.envelope.sm .lo{font-size:8px}
.envelope.sm .seal{width:9px;height:9px}
.envelope.big{max-width:230px;padding:12px 14px}
.envelope.big .lk{font-size:10px}
.envelope.big .lo{font-size:20px}
.envelope.big .seal{width:20px;height:20px}
.t-letter{display:flex;flex-direction:column;align-items:flex-start;gap:6px;width:100%}
.t-letter .meta{padding-left:4px}
/* Opened: the words on a plain sheet under a line saying what they were. */
.letter{width:100%;background:var(--jr-photo);color:var(--jr-photo-ink);border:1px solid var(--color-divider);border-left:3px solid var(--color-text);box-shadow:var(--shadow-sm);padding:10px 12px 12px}
.letter .lk{display:block;font-size:8px;letter-spacing:.14em;text-transform:uppercase;font-weight:600;color:var(--jr-photo-mute);margin-bottom:6px}
.letter .lt{font-size:14px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}
.letter.big{padding:16px 16px 18px}
.letter.big .lk{font-size:10px;margin-bottom:10px}
.letter.big .lt{font-size:16px;line-height:1.5}
.detail .hero-letter{padding:4px 14px 0;display:flex;flex-direction:column;gap:12px}
.detail .hero-letter .note{font-size:12px;line-height:1.45;color:var(--muted);padding:0 4px}
/* The tile's envelope and sheet, a size up, on the post: surfaces and corners instead of paper,
   a frame and a shadow. Ready is a ring of the accent, as on the tile. */
.detail .hero-letter .envelope{max-width:none;width:100%;aspect-ratio:auto;min-height:150px;border:0;border-radius:var(--radius-md);
  background:var(--surface-1);color:var(--text);box-shadow:none;padding:14px 16px}
.detail .hero-letter .envelope .flap{background:linear-gradient(to bottom left,transparent 49.5%,var(--surface-3) 49.5%,var(--surface-3) 51%,transparent 51%) left top/50% 100% no-repeat,
  linear-gradient(to bottom right,transparent 49.5%,var(--surface-3) 49.5%,var(--surface-3) 51%,transparent 51%) right top/50% 100% no-repeat}
.detail .hero-letter .envelope .seal{border-radius:50%;box-shadow:0 0 0 3px var(--surface-1)}
.detail .hero-letter .envelope .lk{color:var(--muted)}
.detail .hero-letter.ready .envelope{box-shadow:inset 0 0 0 2px var(--color-accent)}
.detail .hero-letter.ready .envelope .lo{color:var(--accent-text)}
.detail .hero-letter .letter{border:0;border-radius:var(--radius-md);background:var(--surface-1);box-shadow:none;color:var(--text)}
.detail .hero-letter .letter .lk,.detail .hero-letter .lread span{color:var(--muted)}
/* Ready, not yet opened. The seal goes accent and gets a slow pulse — the one animation in the
   app, because a letter's day comes once and it is allowed to ask for a moment of your attention.
   Everything else about the envelope stays exactly as it was. */
.t-letter.ready .envelope,.hero-letter.ready .envelope{border-color:var(--color-accent);box-shadow:var(--shadow-md)}
.t-letter.ready .envelope .lo,.hero-letter.ready .envelope .lo{color:var(--color-accent)}
.t-letter.ready .envelope .seal,.hero-letter.ready .envelope .seal{animation:jrSeal 2.4s ease-in-out infinite}
@keyframes jrSeal{0%,100%{transform:translate(-50%,-50%) scale(1)}50%{transform:translate(-50%,-50%) scale(1.28)}}
@media (prefers-reduced-motion:reduce){.t-letter.ready .envelope .seal,.hero-letter.ready .envelope .seal{animation:none}}
/* Who has been inside. A letter is read once each, so this is faces and a count, never a like. */
.lread{display:flex;align-items:center;gap:4px;margin-top:10px;padding-top:8px;border-top:1px solid var(--color-divider)}
.lread span{font-size:9px;letter-spacing:.06em;text-transform:uppercase;color:var(--jr-photo-mute);margin-left:2px}
.lread.big{margin:0;padding:0;border:0}
.lread.big span{font-size:10px;color:var(--color-neutral-600)}
/* The banner. Same object as the question's, with the seal on the right where its × would be. */
.ltop .seal{flex:none;align-self:center;width:14px;height:14px;margin-right:15px;border-radius:50%;background:var(--color-accent);animation:jrPip 2.4s ease-in-out infinite}
@keyframes jrPip{0%,100%{transform:scale(1)}50%{transform:scale(1.28)}}
@media (prefers-reduced-motion:reduce){.ltop .seal{animation:none}}
.bigenv{margin-top:12px}
.daycard .th-env{position:relative;background:var(--surface-2);min-height:0;overflow:hidden}
.daycard .th-env i{position:absolute;left:50%;top:50%;width:7px;height:7px;border-radius:50%;transform:translate(-50%,-50%);background:var(--color-accent)}

/* ─── mentions ──────────────────────────────────────────────────────────── */
/* A name set in ink, underlined like a link but in the app's own colour: it goes to a person,
   not to a page. Inside a label strip it keeps the strip's colour. */
a.mention{color:inherit;font-weight:700;text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:2px}
.mentionbar{display:flex;gap:6px;padding:8px 0 2px}
.mentionbar button{flex:none;display:inline-flex;align-items:center;gap:6px;min-height:36px;padding:0 10px 0 6px;border:1px solid var(--color-text);background:var(--color-bg);color:var(--color-text);font:inherit;font-size:13px;font-weight:600;cursor:pointer}
.mnote{margin-top:6px;font-size:11px;color:var(--color-neutral-600)}
.detail .composer{flex-direction:column;gap:0}
.detail .composer .row{display:flex;gap:6px;align-items:flex-end;min-height:48px;padding:0 4px 0 5px;
  border-radius:24px;background:var(--surface-1)}
/* The ring goes round the pill, not round the words inside it. */
.detail .composer .row:focus-within{outline:2px solid var(--color-accent);outline-offset:2px}
.detail .composer .mentionbar{padding:0 0 8px}
/* The same pill as the composer's (.compose .mentionbar): one MentionBar, drawn one way. */
.detail .composer .mentionbar button{border:0;border-radius:18px;background:var(--surface-1);color:var(--text);font-weight:800;padding:0 12px 0 6px}


/* ─── question of the day ────────────────────────────────────────────────── */
/* Today's question, at the top of the spread. It is the one thing on a spread that asks something
   of you, so it sits above the days rather than in them — and it can be put away for the day,
   because the post is on its day sheet either way. */
.topband{display:flex;align-items:stretch;margin:6px 14px 8px;border-radius:var(--radius-md);overflow:hidden;background:var(--surface-1);color:var(--text)}
.topband .body{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px;align-items:flex-start;text-align:left;
  border:0;background:none;color:inherit;font:inherit;cursor:pointer;padding:12px 4px 12px 14px}
.topband .k{font-family:var(--font-heading);font-weight:800;font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--accent-text)}
.topband .q{font-family:var(--font-heading);font-weight:800;font-size:15px;line-height:1.25;letter-spacing:-.01em;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.topband .who{font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.topband .x{flex:none;width:44px;border:0;background:none;color:var(--text-2);cursor:pointer;display:grid;place-items:center}
.topband .x:active{opacity:1}
/* The sheet the day's first opener sees. It borrows the what's-new furniture, because it is the
   same object: something the app has to say, once, with a way out. */
.sheet.qotd{padding-bottom:12px}
.qotd-lead{margin:2px 0 14px;font-size:14px;line-height:1.5;color:var(--text-2)}
/* The card, as it will look on the spread: the promise is that asking makes exactly this — the
   spread's question band, a card on the surface with its kicker in the accent's text colour. */
.qotd-card{background:var(--surface-1);border:0;border-radius:var(--radius-md);color:var(--text);margin-bottom:12px}
.qotd-card .qbar{background:none;color:var(--accent-text);padding:12px 14px 0}
.qotd-card .qbar .from{font-family:var(--font-heading);font-weight:800;font-size:10px;letter-spacing:.1em;text-transform:uppercase}
.qotd-card .qbody{padding:6px 14px 14px}
.qotd-card .qbody .q{font-family:var(--font-heading);font-weight:800;font-size:18px;line-height:1.25;letter-spacing:-.02em;
  width:100%;border:0;background:none;color:inherit;padding:0;resize:none;outline:none;display:block;
  font-size:18px !important}
.qotd-card .qbody .q:focus{outline:none}
.qotd-card:focus-within{outline:2px solid var(--color-accent);outline-offset:2px}
.qotd-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:12px}
.qotd-foot .pot{font-size:12px;color:var(--muted)}
.qotd-card .qline{margin-top:14px}
.qotd-card .qline .rule{display:block;min-height:20px;border-bottom:1px solid var(--rule)}
.qotd-shuffle{display:inline-flex;align-items:center;gap:6px;min-height:44px;padding:0 4px;font-size:13px;font-weight:800;color:var(--accent-text)}
.sheet.qotd .btn-ghost.h44{color:var(--text-2);font-weight:800}
.sheet.qotd .btn-primary.h48,.whatsnew .btn-primary.h48{border-radius:var(--radius-md);font-weight:800}
/* The switch in the journal's settings: a pill with a round knob, the accent's fill when it is on. */
.qswitch{display:flex;align-items:flex-start;gap:12px;width:100%;padding:10px 0;border:0;background:none;color:var(--color-text);font:inherit;text-align:left;cursor:pointer}
.qswitch .bd{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.qswitch .nm{font-family:var(--font-heading);font-weight:800;font-size:15px;line-height:1.2}
.qswitch .mt{font-size:12px;line-height:1.4;color:var(--muted)}
.qswitch .sw{flex:none;width:44px;height:26px;border:0;border-radius:13px;background:var(--surface-2);display:block;position:relative;margin-top:2px}
.qswitch .sw i{position:absolute;left:4px;top:4px;width:18px;height:18px;border-radius:50%;background:var(--muted);display:block;transition:left .12s ease,background .12s ease}
.qswitch.on .sw{background:var(--accent-fill)}
.qswitch.on .sw i{left:22px;background:#fff}
.potrow{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-top:2px}
.potrow .n{font-size:12px;color:var(--muted)}
.potrow .btn-ghost{font-weight:800}
@media (prefers-reduced-motion:reduce){.qswitch .sw i{transition:none}}

/* ─── the day's edge ──────────────────────────────────────────────────────
   One boundary per level, and which one is a choice. The sheet carries no border of its own; the
   app root says which edge every day gets. `paper` ships: the paper edge and the desk showing
   between days *is* the boundary, which is what a notebook does. */
/* The day's edge is its heading now: the mosaic has no sheet, so there is nothing to put a shadow
   or a rule on, and the class on the root (lookups.js, applyEdge) draws nothing. The rule, the box
   and the box-round-the-newest-day were the other choices while this was a setting in Me. */

/* ─── where we've been: one map, a pin per place ─────────────────────────── */
.been{flex:1;padding-bottom:24px}
/* The picture is only the map. The pins go on top, so each one is a button and stays crisp. */
.beenmap{position:relative;margin:12px 14px 8px;background:var(--surface-1);padding:0;border-radius:var(--radius-md);overflow:hidden}
.beenmap img{display:block;width:100%;height:auto;background:var(--surface-1)}
.beenmap .credit{position:absolute;right:8px;top:8px;border-radius:4px;font-size:7px;line-height:1;letter-spacing:.02em;padding:2px 4px;
  background:rgba(255,255,255,.78);color:#201e1d;pointer-events:none}
.bpin{position:absolute;width:16px;height:16px;margin:-6px 0 0 -8px;padding:0;border:0;border-radius:50%;cursor:pointer;
  background:var(--color-accent);box-shadow:0 0 0 2px #fff;display:block}
.bpin b{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:5px;height:5px;border-radius:50%;background:#fff;display:block;pointer-events:none}
.bpin::after{content:'';position:absolute;left:50%;top:100%;transform:translateX(-50%);width:0;height:0;pointer-events:none;
  border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid var(--color-accent)}
.bpin.on{background:#1f1d1c;box-shadow:0 0 0 2px #fff,0 0 0 4px #1f1d1c;z-index:3}
.bpin.on::after{border-top-color:#1f1d1c}
/* The label a tapped pin raises: it points down at its own pin, and opens the post. */
.bcard{position:absolute;transform:translate(-50%,calc(-100% - 16px));z-index:4;pointer-events:none}
.bcard button{pointer-events:auto;border:0;border-radius:12px;cursor:pointer;font:inherit;text-align:left;background:var(--sel-bg);
  color:var(--sel-fg);padding:7px 11px;display:block;max-width:190px;box-shadow:var(--shadow-md)}
.bcard .nm{display:block;font-family:var(--font-heading);font-weight:800;font-size:12px;line-height:1.2;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.bcard .dy{display:block;font-size:9px;letter-spacing:.08em;text-transform:uppercase;opacity:.7;margin-top:2px}
/* The little heading over a list — "EVERYWHERE YOU HAVE BEEN", and the count at the other end. */
.lastused{padding:14px 16px 0;font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--color-neutral-600);display:flex;align-items:center;justify-content:space-between;gap:12px}
.been .lastused{padding:14px 18px 4px;font-weight:600;color:var(--muted)}
.beenlist{padding-bottom:8px}
.brow{display:flex;align-items:center;gap:12px;width:100%;padding:9px 16px;min-height:56px;border:0;background:none;
  color:var(--color-text);font:inherit;text-align:left;cursor:pointer;border-bottom:1px solid var(--color-divider)}
.been .brow{width:calc(100% - 36px);margin:0 18px;padding:9px 0;border-bottom-color:var(--rule)}
.brow .th{width:44px;height:34px;flex:none;position:relative;background:var(--color-neutral-300);overflow:hidden}
.been .brow .th{width:46px;height:46px;border-radius:12px;background:var(--surface-1)}
.brow .th img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.brow .bd{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.brow .nm{font-family:var(--font-heading);font-weight:800;font-size:14px;line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.brow .mt{font-size:11px;color:var(--color-neutral-600);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.brow svg{flex:none;color:var(--color-neutral-600)}

/* ─── doodle ────────────────────────────────────────────────────────────── */
/* Drawing takes the whole screen: the tools under the header, the sheet everything below them, and
   the tray and tab bar step out until Done. The sheet is paper-white in both themes, like a photo. */
/* On paper in both themes, because that is what a doodle posts as — ink on a dark well is ink
   nobody can see. */

/* ─── collage ───────────────────────────────────────────────────────────── */
/* The browser's own image drag has to be off, or it swallows the pointer events the reorder runs on. */
/* The number is the whole explanation of why the order matters: 1 is the big one on the left. */
.wn-art .page{position:absolute;top:8px;width:74px;height:94px;background:var(--surface-1);border:0;border-radius:12px;display:grid;place-items:center;box-shadow:0 0 0 2px var(--bar)}
.wn-art .p1{left:calc(50% - 74px)}
.wn-art .p2{left:calc(50% - 44px);top:4px;background:var(--surface-2)}
.wn-art .p3{left:calc(50% - 14px);top:0;background:var(--accent-fill);color:var(--on-accent)}
.wn-title{font-family:var(--font-heading);font-weight:800;font-size:24px;line-height:1.1;letter-spacing:-.02em;margin:0 0 10px}
.wn-body{font-size:14px;line-height:1.5;color:var(--text-2);margin:0 0 16px;text-wrap:pretty}
/* The steps as a ruled list, each number in a round mark. */
.wn-steps{list-style:none;margin:0 0 20px;padding:0;display:grid;gap:0;border:0}
.wn-steps li{display:flex;align-items:flex-start;gap:12px;padding:11px 0;border-bottom:1px solid var(--rule);font-size:14px;line-height:1.4}
.wn-steps li:last-child{border-bottom:0}
.wn-steps b{flex:none;width:22px;height:22px;border-radius:50%;background:var(--surface-1);color:var(--text);font-family:var(--font-heading);font-weight:800;font-size:11px;display:grid;place-items:center;margin-top:-1px}

/* ─── people ────────────────────────────────────────────────────────────── */
/* One row per person, and the number is the point. Every selector is under .people.

   What this replaces: a grid of taped polaroids with the name in a translucent box over the face.
   Tape is a spread idiom — it belongs where paper is the metaphor — and a name behind translucency
   measured about 2:1 over a light photograph. A directory is a list. */
.people .hdr{padding:22px 14px 10px 18px;display:flex;align-items:center;gap:10px}
.people .hdr .h1{flex:1;min-width:0}
/* Invite, not Add: on a screen made of people, "Add" does not say add what. Filled like Home's
   Join, drawn 38px inside the 44px it has always been to hit. */
.people .invite{flex:none;display:flex;align-items:center;gap:6px;min-height:44px;padding:0 10px 0 8px;
  border:3px solid transparent;border-radius:17px;background:var(--surface-1);background-clip:padding-box;
  color:var(--color-text);cursor:pointer;text-align:left;
  font:inherit;font-family:var(--font-heading);font-weight:800;font-size:13px;line-height:1}
.people .invite svg{width:13px;height:13px;stroke-width:2.4}
.people .sum{padding:14px 18px 4px;font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  font-weight:600;color:var(--muted)}
/* The whole width is the target; the rule is drawn inside the 18px gutter. */
.people .prow{display:flex;align-items:stretch;gap:12px;width:100%;padding:12px 18px;
  border:0;background:linear-gradient(var(--rule),var(--rule)) center bottom / calc(100% - 36px) 1px no-repeat;
  color:var(--color-text);font:inherit;text-align:left;cursor:pointer}
/* The picture is a picture: full colour, no frame and no rotation — and round, as every face is. */
.people .prow .face{width:64px;height:64px;flex:none;font-size:24px;border-radius:50%}
.people .prow .face.pend{display:grid;place-items:center;background:var(--surface-1);
  color:var(--muted);border:1.5px dashed var(--muted);
  font-family:var(--font-heading);font-weight:800}
.people .prow .who{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center;gap:4px}
.people .prow .nm{font-family:var(--font-heading);font-weight:800;font-size:15px;line-height:1.2;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* One line, ellipsised. The figure on the right carries the number, so the end of a long German
   plural is the right thing to lose. */
.people .prow .sub{font-size:12px;color:var(--muted);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.people .prow .num{flex:none;min-width:34px;display:flex;flex-direction:column;align-items:flex-end;
  justify-content:center;gap:1px}
.people .prow .fig{font-family:var(--font-heading);font-weight:800;font-size:20px;line-height:1;
  font-variant-numeric:tabular-nums}
.people .prow .lbl{font-size:9px;letter-spacing:.1em;text-transform:uppercase;font-weight:800;
  color:var(--muted)}
/* A grey nought reads as an invitation. "0 things to remember" four times down a screen read as
   failure, which is the opposite of what an empty book is. */
.people .prow .num.none .fig{color:var(--color-neutral-700)}
/* One line, ellipsised. The figure on the right carries the number, so the end of a long German
   plural is the right thing to lose. */
/* A grey nought reads as an invitation. "0 things to remember" four times down a screen read as
   failure, which is the opposite of what an empty book is. */
.people .foot{padding:14px 18px 24px;font-size:11px;line-height:1.45;color:var(--muted)}
.people .none{padding:26px 18px;text-align:left}
.people .none h2{margin:0;font-family:var(--font-heading);font-weight:800;font-size:26px;line-height:1.05;
  letter-spacing:-.03em}
.people .none p{margin:12px 0 0;font-size:14px;line-height:1.5;color:var(--color-neutral-700)}

/* ─── join / preview / invite / landing / add a person ──────────────────── */
/* Join, Invite and Add a person are forms: the 18px gutter, section labels in the design's caps,
   filled controls, and space rather than 2px rules between sections. */
.join .body,.invite .sec,.addperson .sec{padding:22px 18px}
.join .body{padding-bottom:24px}
.join .k,.invite .k,.addperson .k{font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin-bottom:8px}
.codefield{min-height:56px;font-family:var(--font-heading);font-weight:800;font-size:18px;letter-spacing:.06em;text-transform:uppercase}
.join .err,.addperson .err{font-size:13px;color:var(--color-accent-800);margin-top:8px}
.join .acts,.invite .acts{display:flex;gap:2px;margin-top:12px}
.join .acts .grow,.invite .acts .grow{flex:1}
.join .acts .btn svg,.addperson .send svg{margin-left:auto}
.join .note,.invite .note,.addperson .note{font-size:12px;color:var(--color-neutral-600);margin-top:12px;max-width:34ch}
.join .invites{margin-top:30px;padding-top:0;border-top:0}
.join .invites .hd{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:8px}
.join .invites .hd .k{margin:0;color:var(--color-text)}
.join .invites .n,.invite .hd .n,.addperson .hd .n{font-size:11px;color:var(--color-neutral-600)}
/* An invitation, drawn as Home draws it: a 46px rounded thumbnail, the name, a line, and its word
   as a small tinted pill. */
.inv-row{cursor:pointer;display:flex;align-items:center;gap:12px;min-height:64px;padding:9px 0;border-top:1px solid var(--rule)}
.inv-row .thumb{width:46px;height:46px;flex:none;position:relative;border-radius:12px;background:var(--accent-tint);overflow:hidden}
.inv-row .thumb img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.inv-row .body{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.inv-row .body .n{font-family:var(--font-heading);font-weight:800;font-size:15px;line-height:1.2}
.inv-row .body .m{font-size:13px;line-height:1.3;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.inv-row .look{flex:none;display:grid;place-items:center;min-height:28px;padding:0 12px;border-radius:14px;
  background:var(--accent-tint);color:var(--accent-tint-text);font-family:var(--font-heading);
  font-size:11px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}
.join .none,.addperson .none{font-size:13px;color:var(--color-neutral-600)}

.join-preview .who{flex:1;font-size:12px;line-height:1.3;min-width:0}
.join-preview .who b{font-weight:600;display:block}
.join-preview .who span{color:var(--color-neutral-600);display:block}
.join-preview .body,.landing .mid{padding:30px 20px 24px;display:flex;flex-direction:column;align-items:center;text-align:center}
.bigcover{position:relative;width:160px;background:var(--color-bg);padding:6px 6px 8px;box-shadow:var(--shadow-md);transform:rotate(-3deg)}
/* Looking before you join, and the invite link's own page: the cover as Home now draws one — a
   picture with 14px corners, no frame, no tape, no tilt. */
.join-preview .bigcover,.landing .bigcover{padding:0;border-radius:14px;overflow:hidden;background:var(--surface-1);box-shadow:none;transform:none}
.join-preview .bigcover .tape,.landing .bigcover .tape{display:none}
.landing .bigcover{width:180px}
.join-preview h1,.landing h1{font-family:var(--font-heading);font-weight:800;font-size:32px;line-height:1.02;letter-spacing:-.03em;margin:24px 0 6px}
.landing h1{font-size:36px;margin:6px 0 10px}
.join-preview .k,.landing .k{font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin:0}
.landing .mid>.k{margin-top:22px}
.chips{display:flex;flex-wrap:wrap;justify-content:center;gap:6px;margin-top:16px}
.landing .chips{margin-top:0}
.pchip{display:flex;align-items:center;gap:6px;font-size:13px;padding:4px 10px 4px 4px;border:1px solid var(--color-divider)}
.join-preview .pchip,.landing .pchip{border:0;border-radius:15px;background:var(--surface-1);font-weight:600}
.join-preview .stats,.landing .stats{font-size:12px;color:var(--muted);margin-top:10px}
/* And the screen closes on the buttons, so the middle is centred on what it is about rather than
   top-aligned with 380px of grey under it — see `.landing .mid` below. */
.join-preview p,.landing p{font-size:14px;line-height:1.45;margin:22px 0 0;max-width:32ch;text-align:left;align-self:stretch;color:var(--text-2)}
/* The two ways on at the foot: no rule over them, the primary the one red fill, the other filled quiet. */
.join-preview .foot,.landing .foot{padding:10px 18px 16px;padding-bottom:calc(16px + env(safe-area-inset-bottom));border:0;display:grid;gap:8px;flex:none}
.join-preview .foot .btn,.landing .foot .btn{margin:0;border-radius:var(--radius-md);font-weight:800}
.landing{display:flex;flex-direction:column}
.landing .top{display:flex;justify-content:space-between;align-items:center;padding:16px 18px 12px;padding-top:calc(16px + env(safe-area-inset-top));border:0}
.landing .mark{font-family:var(--font-heading);font-weight:800;font-size:11px;letter-spacing:.1em;padding:5px 8px;border-radius:var(--radius-sm);background:var(--sel-bg);color:var(--sel-fg)}
.landing .mid{flex:1;justify-content:center}

.invite .to{font-size:12px;color:var(--color-neutral-600);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:45%;flex:none}
.invite .sec{border-bottom:0}
.invite .sec.last,.addperson .sec.last{border-bottom:0;padding-top:6px}
/* The code, one filled chip per part: no tilt, no ink strips, no shadow. */
.codestrips{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px;margin-top:8px}
.codestrips span{background:var(--surface-1);color:var(--color-text);font-family:var(--font-heading);font-weight:800;font-size:20px;letter-spacing:.1em;padding:8px 12px;line-height:1.1;border-radius:12px}
.invite .link{font-size:13px;color:var(--color-neutral-600);margin-top:14px;overflow-wrap:anywhere}
.invite .acts.mail{margin-top:18px}
.invite .acts.mail .grow{flex:1;min-height:44px}
.invite .hd,.addperson .hd{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:4px}
.invite .hd .k,.addperson .hd .k{margin:0;color:var(--color-text)}
.invite .mrow,.addperson .mrow{display:flex;align-items:center;gap:10px;min-height:48px;border-top:1px solid var(--rule);font-size:14px}
.invite .mrow .n,.addperson .mrow .n{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.invite .mrow .role{font-size:11px;color:var(--color-neutral-600);flex:none}
.addperson .mrow .two{flex:1;min-width:0;display:flex;flex-direction:column}
.addperson .mrow .two .n{flex:none}
.addperson .mrow .two .m{font-size:11px;color:var(--color-neutral-600)}
.btn.small{min-height:36px;padding:0 6px;font-size:12px;flex:none}
.knownrow{padding:12px 0 4px;border-top:1px solid var(--rule)}
.knownrow .hint{font-size:12px;color:var(--color-neutral-600);padding:0 0 8px;display:block}
.chip-btn{min-height:40px;padding:0 12px 0 6px;gap:8px}
.tofield{min-height:52px}
.addperson .send{margin:18px 0 0}
.handlerow{display:flex;align-items:center;gap:10px}
.handlerow .handle{background:var(--surface-1);color:var(--color-text);font-family:var(--font-heading);font-weight:800;font-size:18px;letter-spacing:.12em;padding:8px 12px;border-radius:12px;flex:none}
.handlerow .txt{flex:1;font-size:12px;color:var(--color-neutral-600)}

/* ─── knowledge book ────────────────────────────────────────────────────── */
/* One continuous sheet, not four cards. Every selector is under .book.

   The cards drew a box around four things their own heads already separated — and those heads were
   10px grey, the weakest mark on the screen doing the most important job. A band between two 2px
   ink rules is the strongest separation this app has, so the category is what you see first and the
   fact second. Adding is one dock at the foot rather than four inputs and four accent Add links:
   one field that asks which beats four that each ask what, and it frees the accent for the single
   action the screen exists for. */
.book .jhead{padding:10px 18px 0;border-bottom:0}
.book .row1{display:flex;align-items:center;gap:10px}
/* Pulled back by half the padding so the glyph sits optically flush with the edge. */
.book .row1 .nav{flex:none;width:44px;height:44px;display:grid;place-items:center;padding:0;
  border:0;background:none;color:var(--color-text);cursor:pointer}
.book .row1 .nav:first-child{margin-left:-11px}
.book .row1 .nav:last-child{margin-right:-11px}
.book .row1 .face{width:36px;height:36px;flex:none;font-size:15px;border-radius:50%;cursor:pointer}
.book .row1 .h1{flex:1;min-width:0;margin:0;font-size:22px;line-height:1;letter-spacing:-.03em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* "Knowledge book · 7 things" said what the screen obviously is. The next person's name is worth
   the room; "Swipe for the next person" is an instruction and a name is information. */
.book .row2{display:flex;align-items:baseline;gap:8px;padding:7px 0 11px;font-size:10px;
  letter-spacing:.11em;text-transform:uppercase;font-weight:600;color:var(--color-neutral-700)}
.book .row2 .n{flex:none;font-variant-numeric:tabular-nums}
.book .row2 .dot{flex:none;color:var(--color-neutral-400)}
.book .row2 .nx{flex:1;min-width:0;text-transform:none;letter-spacing:0;font-weight:400;font-size:11px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.book .body{flex:1;min-height:0;overflow:auto}

/* a category: a section label over a ruled list, as Me's groups are, but in full ink at 800 —
   the category is still what you see first. No band and no rules round it: the page and the
   space above it do the separating now, as everywhere else in the softer design. */
.book .band{display:flex;align-items:baseline;gap:8px;padding:20px 18px 6px;
  background:none;border:0}
.book .band .t{flex:1;min-width:0;font-size:11px;letter-spacing:.1em;text-transform:uppercase;font-weight:800}
.book .band .n{flex:none;font-size:11px;font-weight:800;color:var(--muted);font-variant-numeric:tabular-nums}
.book .bare{margin:0 18px;padding:11px 0 12px;border-bottom:1px solid var(--rule);
  font-size:12px;color:var(--color-neutral-700)}
.book .fact{display:flex;align-items:center;gap:10px;min-height:52px;margin:0 18px;padding:6px 0;
  border-bottom:1px solid var(--rule)}
.book .fact .x{flex:1;min-width:0;font-size:15px;line-height:1.35;overflow-wrap:anywhere}
/* Where it came from, as a mark rather than red text in the middle of the line: provenance matters
   the second time you read a fact and never the first. */
/* A small caps chip on the surface, drawn 24px tall inside the 44px it is to hit. */
.book .fact .post{flex:none;position:relative;isolation:isolate;display:flex;align-items:center;gap:4px;padding:0 9px;
  min-height:44px;margin:-8px 0;border:0;background:none;cursor:pointer;
  font:inherit;font-family:var(--font-heading);font-weight:800;font-size:9px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--color-neutral-700)}
.book .fact .post::before{content:'';position:absolute;left:0;right:0;top:10px;bottom:10px;z-index:-1;
  border-radius:12px;background:var(--surface-1)}
.book .fact .forget{flex:none;width:44px;height:44px;margin-right:-14px;display:grid;place-items:center;padding:0;
  border:0;border-radius:50%;background:none;color:var(--color-neutral-700);cursor:pointer}
.book .foot{padding:16px 18px 22px;font-size:11px;line-height:1.5;color:var(--color-neutral-700)}

/* a book with nothing in it */
.book .none{padding:26px 18px 0}
.book .none h2{margin:0;font-family:var(--font-heading);font-weight:800;font-size:25px;line-height:1.05;
  letter-spacing:-.03em}
.book .none p{margin:12px 0 0;font-size:14px;line-height:1.5;color:var(--color-neutral-700)}
.book .none .starts{margin-top:22px;padding:0 0 4px;border-top:0;
  font-size:10px;letter-spacing:.1em;text-transform:uppercase;font-weight:600;color:var(--muted)}
.book .none .srow{display:flex;align-items:center;min-height:52px;border-bottom:1px solid var(--rule);
  font-size:11px;letter-spacing:.12em;text-transform:uppercase;font-weight:800}
.book .none .srow .n{margin-left:auto;font-size:11px;color:var(--color-neutral-700);font-variant-numeric:tabular-nums}

/* the dock: which, then what, then the one accent button on the screen */
.book .dock{flex:none;border-top:2px solid var(--rule-head);background:var(--bar);padding:10px 18px 12px}
/* Its own names. `.chips` is the join screen's, and it centres them; `.kchip` is Home's journal
   filter. Both would have applied here, and the one that is only *mostly* overridden is the one
   that comes back as a bug six months later — see the note at the head of the reminders block. */
/* One row that scrolls, rather than two or three that wrap. Eight categories wrapped to two rows
   in English and three in German, so the dock's height moved with the language and the field it is
   asking about sat lower on the screen in one language than the other. A row that scrolls is the
   same height in every language, and it is the shape this app already uses for a strip of chips —
   Home's filters and the mention bar are both .hscroll.
   It bleeds: -12px of margin against the dock's padding, put back as the scroller's own, so the
   first chip still lines up with the field under it and the eighth runs off the true edge of the
   screen. A chip cut in half at that edge is the whole of the affordance — the same one the
   sticker strip and Home's filters rely on. flex-start rather than anything centred: with the row
   overflowing, any other justification puts the first chips somewhere scrolling cannot reach. */
.book .catrow{display:flex;flex-wrap:nowrap;justify-content:flex-start;gap:6px;
  margin:0 -18px 8px;padding:0 18px;scroll-padding-inline:18px}
/* The filter chip, as on Home: filled, 14px corners, the picked one the light chip. */
.book .cat{flex:none;min-height:34px;display:inline-flex;align-items:center;padding:0 13px;cursor:pointer;
  border:0;border-radius:14px;background:var(--surface-1);color:var(--text-2);
  font:inherit;font-family:var(--font-heading);font-weight:800;font-size:13px;line-height:1;text-align:left}
.book .cat.on{background:var(--sel-bg);color:var(--sel-fg)}
.book .write{display:flex;gap:8px}
.book .write .input{flex:1;min-width:0;height:48px;padding:0 11px;font-size:16px}
.book .write .keep{flex:none;min-height:48px;margin:0;padding-inline:16px;
  font-size:12px;letter-spacing:.1em;text-transform:uppercase}

/* The chat announcement's picture: the real blocks, one each way. */
.wn-art.chatart{position:static;height:auto;padding:12px 0 6px;display:flex;flex-direction:column;gap:6px;align-items:stretch}
.wn-art.chatart .b{height:22px;border-radius:11px;display:block}
.wn-art.chatart .them{background:var(--color-surface);width:62%;align-self:flex-start}
.wn-art.chatart .them.short{width:44%}
.wn-art.chatart .mine{background:var(--bubble-own);width:52%;align-self:flex-end}

/* The file announcement's picture: the card the spread shows, with the tab that names the kind. */
.wn-art.fileart{position:static;height:auto;display:flex;flex-direction:column;gap:8px;align-items:flex-start;
  background:var(--surface-1);border-radius:var(--radius-md);padding:12px 12px 14px}
.wn-art.fileart .kind{background:var(--sel-bg);color:var(--sel-fg);border-radius:var(--radius-sm);font-family:var(--font-heading);
  font-weight:800;font-size:10px;letter-spacing:.1em;padding:5px 7px}
.wn-art.fileart .l{height:9px;border-radius:5px;background:var(--surface-3);width:72%;display:block}
.wn-art.fileart .l.short{width:40%}

/* The covered-photo announcement's picture: glass with the plate in the middle, and nothing
   behind it that anybody could squint at — which is the announcement. */
.wn-art.coverart{position:static;height:110px;display:grid;place-items:center;
  background:linear-gradient(120deg,var(--color-neutral-300),var(--color-surface),var(--color-neutral-300));
  border-radius:var(--radius-md)}
.wn-art.coverart .plate{width:96px;height:26px;border-radius:13px;background:rgba(28,26,25,.72);display:block}

/* The unread announcement's picture: the bar itself, on its own light ground, because the thing
   being announced is a control and not a post. */
.wn-art.walkart{position:static;height:auto;display:flex;align-items:center;gap:12px;min-height:56px;padding:8px;
  background:var(--surface-1);border-radius:var(--radius-md)}
.wn-art.walkart .n{flex:none;width:40px;height:40px;border-radius:50%;background:var(--accent-fill);color:#fff;display:grid;
  place-items:center;font-family:var(--font-heading);font-weight:800;font-size:20px;line-height:1}
.wn-art.walkart .t{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center;gap:6px;padding:0}
.wn-art.walkart .t i{display:block;height:7px;border-radius:4px;background:var(--accent-text)}
.wn-art.walkart .t i.w{height:10px;width:62%;background:var(--text)}
.wn-art.walkart .t i.k{width:34%}
.wn-art.walkart .go{flex:none;width:40px;height:40px;border-radius:50%;background:var(--surface-2);display:grid;place-items:center;color:var(--text)}

/* The question announcement's picture: the card in miniature, one line filled and one still blank. */
.wn-art.qart{position:static;height:auto;padding:12px 14px 10px;display:flex;flex-direction:column;gap:7px;background:var(--surface-1);
  border-radius:var(--radius-md)}
.wn-art.qart .ink{height:12px;border-radius:6px;background:var(--color-text);width:70%}
.wn-art.qart .q{height:14px;border-radius:7px;background:var(--surface-3);width:86%}
.wn-art.qart .line{display:flex;align-items:flex-end;gap:7px}
.wn-art.qart .line i{width:12px;height:12px;border-radius:50%;background:var(--muted);opacity:.45;margin-bottom:3px}
.wn-art.qart .line b{flex:1;height:1px;background:var(--rule);display:block}
.wn-art.qart .line.filled i{opacity:1;background:var(--color-accent)}
.wn-art.qart .line.filled b{height:2px;background:var(--color-accent)}

/* ─── place: a map fragment, cut to the corners ──────────────────────────── */
/* The streets are two repeating gradients and the roads are absolutely positioned lines, so nothing
   here is fetched. They cross off centre on purpose: dead centre reads as a target, not a map.
   Since the softer restyle it is drawn as the tiles draw it everywhere — no paper mount, 14px
   corners, the name on a dark chip and the pin round with its tip still on the spot. The tile and
   the post scope their own sizes on top of this. */
.mapcard{--pin:18px;background:var(--surface-1);border:0;border-radius:var(--radius-md);overflow:hidden;padding:0;box-shadow:none;
  width:100%;max-width:172px;align-self:start;justify-self:start}
.mapcard .map{position:relative;aspect-ratio:4/3;background:var(--color-surface);overflow:hidden;
  background-image:
    repeating-linear-gradient(90deg, var(--color-neutral-300) 0 1px, transparent 1px 19px),
    repeating-linear-gradient(0deg,  var(--color-neutral-300) 0 1px, transparent 1px 19px)}
.mapcard .road{position:absolute;background:var(--color-neutral-400)}
.mapcard .road.h{left:0;right:0;top:43%;height:2px}
.mapcard .road.v{top:0;bottom:0;left:57%;width:2px}
/* The pin. A round head with a punched centre and a narrower point under it whose tip is the
   location. --pin drives all of it so the four sizes are one number. */
.mapcard .pin{position:absolute;left:57%;top:43%;width:var(--pin);height:var(--pin);border-radius:50%;
  transform:translate(-50%,calc(-100% - var(--pin) * .35));background:var(--color-accent);
  box-shadow:0 0 0 2px var(--jr-photo)}
.mapcard .pin b{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:block;border-radius:50%;
  width:calc(var(--pin) / 3);height:calc(var(--pin) / 3);background:var(--jr-photo)}
.mapcard .pin::after{content:'';position:absolute;left:50%;top:calc(100% - var(--pin) * .2);transform:translateX(-50%);
  width:0;height:0;border-left:calc(var(--pin) * .3) solid transparent;
  border-right:calc(var(--pin) * .3) solid transparent;
  border-top:calc(var(--pin) * .55) solid var(--color-accent)}
.mapcard .name{position:absolute;left:6px;right:auto;max-width:calc(100% - 12px);bottom:6px;border-radius:8px;background:rgba(28,26,25,.72);color:#fff;
  font-family:var(--font-heading);font-weight:800;font-size:9px;letter-spacing:.1em;text-transform:uppercase;
  padding:4px 7px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block}
/* With a spot, the map is a picture: the cut-out the server drew round it, under the same pin at the
   same point. The credit is the map's licence talking, and is dropped where it could not be read. */
.mapcard .map img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.mapcard.real .map{background-image:none}
.mapcard .credit{position:absolute;right:3px;top:3px;font-size:6px;line-height:1;letter-spacing:.02em;padding:2px 3px;
  background:rgba(255,255,255,.78);color:#201e1d;pointer-events:none}
.mapcard.big .credit{font-size:8px}
.mapcard.sm .credit{display:none}
.mapcard.big{--pin:26px;max-width:none;padding:0}
.mapcard.big .name{font-size:11px;left:10px;bottom:10px;padding:5px 10px;border-radius:10px}
.mapcard.sm{--pin:12px;max-width:120px;border-radius:12px}
.mapcard.sm .name{font-size:7px;padding:3px 5px;border-radius:6px;left:5px;bottom:5px}

/* ─── link: a link ───────────────────────────────────────────────────────── */
/* Drawn as the tiles and the post draw it since the softer restyle — a card on the surface with
   corners, the way out a round mark, the title in ink and underlined, the address muted — so the
   composer's preview of it is what lands. The tile and the post scope their sizes on top. */
.linkrow{display:flex;align-items:center;gap:12px;background:var(--surface-1);border:0;border-radius:var(--radius-md);
  padding:12px 14px;width:100%;min-width:0;color:var(--text)}
.linkrow .launch{width:22px;height:22px;flex:none;border-radius:50%;background:var(--text);color:var(--page);display:grid;place-items:center;margin-top:0}
.linkrow .body{flex:1;min-width:0;display:flex;flex-direction:column}
.linkrow .ttl{font-family:var(--font-heading);font-weight:800;font-size:15px;line-height:1.3;color:var(--text);text-decoration:underline;
  text-decoration-thickness:1px;text-underline-offset:2px;overflow-wrap:anywhere}
.linkrow .url{font-size:11px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:2px}
.linkrow .at{margin-top:1px;flex:none}
.linkrow.big{padding:12px 14px 13px}
.linkrow.big .launch{width:28px;height:28px}
.linkrow.big .ttl{font-size:19px}
.linkrow.big .url{white-space:normal;word-break:break-all}
.linkrow.sm{padding:6px 8px;gap:6px;border-radius:10px}
.linkrow.sm .launch{width:11px;height:11px}
.linkrow.sm .ttl{font-size:12px}
.linkrow.sm .url{font-size:9px}
.detail .hero-link{padding:4px 14px 0}
.detail .hero-link a{text-decoration:none;display:block}
/* The tile's link a size up: a surface with corners, the way out a round mark, the title in ink. */
.detail .hero-link .linkrow{align-items:center;gap:12px;border:0;border-radius:var(--radius-md);background:var(--surface-1);padding:14px 16px}
.detail .hero-link .linkrow .launch{width:28px;height:28px;margin:0;border-radius:50%;background:var(--text);color:var(--page)}
.detail .hero-link .linkrow .ttl{font-family:var(--font-heading);font-weight:800;color:var(--text);text-decoration:underline}
.detail .hero-link .linkrow .url{color:var(--muted)}

/* ─── a covered picture ──────────────────────────────────────────────────── */
/* The frosted glass. Blur alone leaves a soft transparent rim where the filter runs out of pixels
   to average, so the picture is pushed out past its own frame and the box clips it — which is what
   makes this read as glass over a photograph rather than a photograph gone wrong. The saturation
   goes up a touch because blurring pulls colour towards grey and a covered picture should still
   look like it has something in it.
   Asked for straight: "make the photo a little more blurry". The radius and the push go together —
   a wider blur reaches further past the edge for pixels it does not have, so the picture has to be
   pushed out further to keep the rim off the screen. 22 and 1.18 were the first pair, these are the
   second. Faces were still readable at 22 on a big phone, which is most of the point of a cover. */
.media-box.frosted img{filter:blur(34px) saturate(1.4);transform:scale(1.28);pointer-events:none}
/* Where there is no picture at all — one behind a code — the box is paper rather than a hole. */
.media-box.frosted{background:var(--color-surface)}
.media-box.frosted .ph{display:none}
/* The mark: a plate in the middle, in the app's ink, on both the card and the post. */
.covermark{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:3;
  background:var(--color-text);color:var(--color-bg);border:0;font:inherit;padding:6px 10px;
  display:inline-flex;align-items:center;max-width:calc(100% - 16px)}
.covermark .cmb{display:inline-flex;align-items:center;gap:7px;font-size:11px;font-weight:600;
  letter-spacing:.04em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.covermark.act{cursor:pointer}
.covermark.big{padding:0 20px;min-height:48px}
.covermark.big .cmb{font-size:14px;gap:10px}
/* A code is a different promise from a blur, so it is a different colour: the accent is the app
   saying "this one is yours to open", the ink is the app saying "this one is just covered". */
.covermark.locked{background:var(--color-accent);color:#fff}
.posthero .hero-shot.covered{position:relative;display:flex;justify-content:center}
.posthero .hero-shot.covered .media-box{width:100%}
/* The post's own plate: a pill of the dark glass the post's other buttons are, the coded one on the
   deeper accent as on a tile. Its line-height spelled out: the picture's box sets it to nought, and
   the label inside clips to its line, which had left the plate an eye with no word beside it. It
   also wears `act`, and the old bar's `.detail .act` was taking its plate away. */
.posthero .covermark.big{min-height:48px;padding:0 20px;border-radius:24px;line-height:1.2;
  background:rgba(28,26,25,.72);color:#fff}
.posthero .covermark.big .cmb{font-weight:800}
.posthero .covermark.big.locked{background:#d42a10;color:#fff}
.coverask{position:absolute;inset:0;display:grid;place-items:center;padding:0 16px}
.coverask .codebox{display:flex;gap:8px;width:100%;max-width:320px;position:relative;z-index:3}
.coverask .codebox .input{flex:1;min-width:0;min-height:44px}
/* The switch in the composer, in the same two-cell shape the rest of the app's rows use. */
/* The tray's miniature wears the same glass, so the draft shows what the spread will. */

/* ─── a document ─────────────────────────────────────────────────────────── */
/* Not a link, and drawn so that nobody has to be told: the app's own ink rather than link blue,
   and a square tab on the left saying what kind it is. That tab is doing the work an icon would
   do and saying something an icon cannot — PDF and XLSX are different afternoons. */
.filerow{display:flex;align-items:center;gap:10px;background:var(--jr-photo);border:1px solid var(--color-divider);
  padding:9px 11px;width:100%;min-width:0;color:var(--jr-photo-ink)}
.filerow .kind{flex:none;min-width:34px;padding:4px 5px;background:var(--color-text);color:var(--color-bg);
  font-family:var(--font-heading);font-weight:800;font-size:8px;letter-spacing:.1em;text-align:center}
.filerow .body{flex:1;min-width:0;display:flex;flex-direction:column}
.filerow .ttl{font-size:14px;line-height:1.3;font-weight:600;overflow-wrap:anywhere}
.filerow .sub{font-size:11px;color:var(--jr-photo-mute);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.filerow.big{padding:13px 14px;gap:13px}
.filerow.big .kind{min-width:46px;padding:7px 6px;font-size:10px}
.filerow.big .ttl{font-size:18px}
.filerow.big .sub{font-size:12px}
.t-file{width:100%}
/* The first page on the card: a picture, mounted like one, cut at the height a glance needs.
   The page keeps its own proportions and the box takes the top of it — a page is read from the
   top, so that is the part worth showing when there is only room for part. */
.t-file .pdfshot{margin-bottom:8px;overflow:hidden;background:var(--jr-photo);
  border:1px solid var(--color-divider);max-height:230px}
.t-file .pdfshot .media-box img{object-position:50% 0}
.detail .hero-file{padding:4px 14px 0;display:grid;gap:10px;justify-items:start}
.detail .hero-file .filerow{width:100%;border:0;border-radius:var(--radius-md);background:var(--surface-1);color:var(--text);padding:14px 16px}
.detail .hero-file .filerow .kind{border-radius:6px;background:var(--text);color:var(--page)}
.detail .hero-file .filerow .sub{color:var(--muted)}
.detail .hero-file .filego{min-height:40px;border-radius:var(--radius-md);background:var(--surface-1);color:var(--text);font-weight:800}
/* The page on the post: the picture of it, whole, on white with its corners rounded, the way a
   page sits on a tile. */
.detail .hero-file .pdfshot{width:100%;background:var(--jr-photo);border:0;border-radius:var(--radius-md);overflow:hidden;
  cursor:zoom-in}
.detail .hero-file .pdfshot .media-box{max-height:62vh}
@supports (height:1svh){.detail .hero-file .pdfshot .media-box{max-height:62svh}}
/* And the frame, which is only what a document posted before there were pictures of them gets.
   Same ceiling, so a post reads the same either way. */
.detail .hero-file .pdfpage{width:100%;height:min(62vh,640px);background:var(--jr-photo);
  border:0;border-radius:var(--radius-md);overflow:hidden}
.detail .hero-file .pdfpage iframe{width:100%;height:100%;border:0;display:block;background:var(--jr-photo)}
@supports (height:1svh){.detail .hero-file .pdfpage{height:min(62svh,640px)}}
/* The one thing you came for, said in the app's own button vocabulary rather than as a link. */
.filego{display:inline-flex;align-items:center;gap:8px;min-height:44px;padding:0 16px;
  background:var(--color-text);color:var(--color-bg);font-size:13px;font-weight:600;text-decoration:none}
.bigfile{margin-top:16px}
.swapfile{margin-top:10px}

/* ─── question: a form, not a tile ───────────────────────────────────────── */
/* The one card in the app that is a form. The answers are set in Reenie Beanie, which is used for
   exactly one other thing — the date on a day sheet — so an answer reads as handwriting on a printed
   form. They are never set in Archivo. */
.qcard{width:100%;background:var(--jr-photo);border:1px solid var(--color-divider);box-shadow:var(--shadow-sm);color:var(--jr-photo-ink)}
.qbar{display:flex;align-items:center;gap:10px;background:var(--color-text);color:var(--color-bg);padding:5px 9px}
.qbar .from{flex:1;min-width:0;font-family:var(--font-heading);font-weight:800;font-size:8px;letter-spacing:.14em;
  text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.qbar .tally{flex:none;font-family:var(--font-heading);font-weight:800;font-size:8px;letter-spacing:.14em;opacity:.7}
.qbody{padding:11px 12px 11px}
.qbody .q{font-family:var(--font-heading);font-weight:800;font-size:15px;line-height:1.25;letter-spacing:-.01em;text-wrap:pretty;overflow-wrap:anywhere}
.qline{display:flex;align-items:flex-end;gap:8px;margin-top:10px}
/* The person's picture sits on the rule, and stays faint until they have answered — the line reads
   as theirs before it reads as filled. The box itself is .avatar's, so a seat shows whatever that
   person shows everywhere else: their photo, their symbol, or their initial. */
.qline .ini{flex:none;opacity:.45;margin-bottom:4px}
.qline.done .ini{opacity:1}
.qline .rule{flex:1;min-width:0;border-bottom:1px solid var(--jr-photo-ink);min-height:24px;display:flex;
  align-items:flex-end;padding-bottom:3px}
.qline .ans{font-family:'Reenie Beanie',cursive;font-size:20px;line-height:1;color:var(--color-accent-700);overflow-wrap:anywhere}
.qline .turn{font-size:10px;letter-spacing:.1em;text-transform:uppercase;font-weight:600;color:var(--color-accent-700)}
.qline .who{font-size:10px;letter-spacing:.1em;text-transform:uppercase;font-weight:600;color:var(--jr-photo-mute)}
.qmore{margin-top:9px;font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--jr-photo-mute)}
.qcard.big .qbar{padding:7px 12px}
.qcard.big .qbar .from,.qcard.big .qbar .tally{font-size:10px}
.qcard.big .qbody{padding:16px 16px 15px}
.qcard.big .qbody .q{font-size:22px;line-height:1.2;letter-spacing:-.015em}
.qcard.big .qline{gap:10px;margin-top:15px}
.qcard.big .qline .rule{min-height:32px}
.qcard.big .qline .ans{font-size:26px}
.detail .hero-q{padding:4px 14px 0}
/* The question and the poll on the post: the tile's card a size up — a surface with corners, the
   question in ink, its lines in the soft rule, the answers in the accent's text colour. */
.detail .hero-q .qcard{border:0;border-radius:var(--radius-md);background:var(--surface-1);box-shadow:none;color:var(--text);overflow:hidden}
.detail .hero-q .qbar{background:none;color:var(--muted);padding:14px 16px 0}
.detail .hero-q .qbar .from{color:var(--accent-text);letter-spacing:.1em}
.detail .hero-q .qbar .tally{opacity:1;letter-spacing:.1em}
.detail .hero-q .qline .rule{border-bottom-color:var(--rule)}
.detail .hero-q .qline .ans,.detail .hero-q .qline .turn{color:var(--accent-text)}
.detail .hero-q .qline .who,.detail .hero-q .qmore{color:var(--muted)}
.detail .hero-q .pchoice{border-bottom-color:var(--rule)}
.detail .hero-q .pchoice .box{border-color:var(--muted);border-radius:5px;background:none}
.detail .hero-q .pchoice.mine .box{background:var(--color-accent);border-color:var(--color-accent)}
.detail .hero-q .pchoice .n,.detail .hero-q .pchoice.mine .lbl{color:var(--accent-text)}
.detail .hero-q .pchoice .pbar{border-radius:2px}
/* Answering, under the card: a card of its own, filled rather than ruled. */
.detail .answerbox{margin:12px 14px 0;padding:14px;border-radius:var(--radius-md);background:var(--surface-1)}
.detail .answerbox .ak{margin:0 0 8px;font-size:10px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--accent-text)}
.detail .answerbox .row{display:flex;gap:8px;align-items:flex-end}
.detail .answerbox .input{flex:1;min-width:0;min-height:48px;line-height:1.4;max-height:120px;
  resize:none;overflow-y:auto;padding:13px 12px;border-radius:var(--radius-md);background-color:var(--surface-2)}
.detail .answerbox .btn{flex:none}
.detail .answerbox .note{margin-top:8px;font-size:12px;line-height:1.45;color:var(--muted)}
/* The field is surface-2 on a surface-1 box, where the placeholder token is 3.5:1 (dark) and 4.2:1
   (light); muted is 4.5:1 and over on it in both. */
.detail .answerbox .input::placeholder,.cpop .answerbox .input::placeholder{color:var(--muted)}

/* The composer's own previews and tray stickers for the three new treatments. */
/* No seat square on the blank at this size: one ruled line is what a question looks like. */
/* Add → Place: the field with the my-location button beside it, the matches dropped under it. The
   button is a filled 48px square with 14px corners, as tall as the field; on is the light chip. The
   matches are a card of ruled rows lifted off the screen. */
.placefield{display:flex;gap:8px}
.placefield .input{flex:1;min-width:0}
.locbtn{flex:none;width:48px;height:48px;border:0;border-radius:var(--radius-md);background:var(--surface-1);color:var(--text);
  display:grid;place-items:center;cursor:pointer;padding:0}
.locbtn.on{background:var(--sel-bg);color:var(--sel-fg)}
.locbtn.busy{opacity:.5}
.placehits{margin-top:8px;border:0;border-radius:var(--radius-md);overflow:hidden;background:var(--surface-1);box-shadow:0 8px 24px rgba(0,0,0,.18)}
.placehits button{display:flex;flex-direction:column;align-items:flex-start;gap:2px;width:100%;min-height:48px;text-align:left;
  padding:10px 14px;border:0;border-top:1px solid var(--rule);background:none;color:var(--text);font:inherit;cursor:pointer}
.placehits button:first-child{border-top:0}
.placehits button b{font-weight:800;font-size:15px;line-height:1.3}
.placehits button span{font-size:12px;color:var(--muted);line-height:1.3}
.placenote{margin-top:8px;font-size:12px;line-height:1.45;color:var(--muted)}
.bigmap-wrap{margin-top:16px;display:grid;justify-items:stretch;gap:6px}
.bigmap-wrap .mapcard{max-width:none}
/* The shape a lone place takes on the spread: the width of the column, half as tall. */
.bigmap-wrap .mapcard .map{aspect-ratio:2/1}
.bigmap-wrap .mapcard .map img{object-position:57% 43%}
.bigmap-wrap .when{font-size:12px;color:var(--muted)}
.biglink{margin-top:16px}
.biglink .linkrow .ttl{font-size:17px}

/* ─── chat ──────────────────────────────────────────────────────────────── */
/* The list. One row per person you could talk to, whether or not anything has been said. */
.chats .top{padding:22px 18px 10px;display:flex;align-items:center;gap:10px}
.chats .top .h1{margin:0;flex:1;min-width:0}
/* How many people, as a caps chip on the surface rather than loose grey letters. */
.chats .top .count{flex:none;padding:4px 9px;border-radius:14px;background:var(--surface-1);font-size:11px;font-weight:600;
  letter-spacing:.1em;line-height:1.35;text-transform:uppercase;color:var(--text-2)}
/* The row is still the whole width to hit; the rule is drawn inside the 18px gutter, as a ruled
   list is drawn everywhere else, by a 1px background band rather than a border on a narrower box. */
.chatrow{width:100%;min-height:71px;padding:12px 18px;display:flex;align-items:center;gap:12px;text-align:left;
  border:0;background:linear-gradient(var(--rule),var(--rule)) center bottom / calc(100% - 36px) 1px no-repeat;
  color:var(--color-text);font:inherit;cursor:pointer}
.chatrow .avatar{width:46px;height:46px;font-size:19px}
.chatrow .body{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}
.chatrow .line{display:flex;align-items:baseline;gap:8px;min-width:0}
.chatrow b{flex:1;min-width:0;font-family:var(--font-heading);font-weight:800;font-size:15px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.chatrow .tm{flex:none;font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
.chatrow .prev{flex:1;min-width:0;font-size:13px;line-height:1.35;color:var(--muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.chatrow .prev.unread{color:var(--color-text)}
.chatrow .badge{flex:none;min-width:20px;height:20px;padding:0 6px;border-radius:10px;background:var(--accent-fill);color:#fff;
  font-family:var(--font-heading);font-weight:800;font-size:10px;display:grid;place-items:center;line-height:1}
.chats .none{padding:24px 18px;font-size:14px;color:var(--color-neutral-600);max-width:34ch}
/* Chat is the one part of this app that never reaches a page. Saying so is the feature. */
.chats .foot{padding:16px 18px;font-size:12px;line-height:1.45;color:var(--color-neutral-600)}

/* The box. A messenger's behaviour and, since the softer restyle, its shape too: rounded bubbles
   grouped by run, a pill to type in, and the tray as a card floating over the foot. */
.chat{display:flex;flex-direction:column}
.chat .bar{padding:8px 12px 8px 8px;border-bottom:0;background:var(--bar);display:flex;align-items:center;gap:12px;flex:none}
.chat .bar .nm{flex:1;min-width:0;font-family:var(--font-heading);font-weight:800;font-size:17px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.chat .msgs{flex:1;overflow:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;padding:14px 14px 6px;
  display:flex;flex-direction:column}
.chat .none{padding:24px 0;font-size:13px;color:var(--color-neutral-600);text-align:center}
/* A run is one person speaking without interruption: 3px inside it, 12px to the next one. */
.chat .run{display:flex;flex-direction:column;align-items:flex-start;gap:3px;margin-bottom:12px}
.chat .run.mine{align-items:flex-end}
.chat .msg{max-width:78%;padding:9px 13px;font-size:14px;line-height:1.4;text-wrap:pretty;border-radius:18px;
  white-space:pre-wrap;overflow-wrap:anywhere;background:var(--surface-1);color:var(--color-text)}
.chat .run.mine .msg{background:var(--bubble-own);color:#fff}
/* Grouped corners. The corner on the speaker's own side is pinched to 6 where the bubble meets
   another of the same run, so a run reads as one stack: first, middle, last. One on its own is
   round all over. The last wrapper is the second-last child, because the run's time follows it. */
.chat .run.mine .mwrap:first-child:not(:nth-last-child(2)) .msg{border-radius:18px 18px 6px 18px}
.chat .run.mine .mwrap:not(:first-child):not(:nth-last-child(2)) .msg{border-radius:18px 6px 6px 18px}
.chat .run.mine .mwrap:nth-last-child(2):not(:first-child) .msg{border-radius:18px 6px 18px 18px}
.chat .run:not(.mine) .mwrap:first-child:not(:nth-last-child(2)) .msg{border-radius:18px 18px 18px 6px}
.chat .run:not(.mine) .mwrap:not(:first-child):not(:nth-last-child(2)) .msg{border-radius:6px 18px 18px 6px}
.chat .run:not(.mine) .mwrap:nth-last-child(2):not(:first-child) .msg{border-radius:6px 18px 18px 18px}
/* Once per run, under its last block and centred — a time on every line is noise. */
.chat .mtime{align-self:center;padding-top:6px;font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums}
/* The day, centred between two hairlines like the time under a run. */
.chat .dayline{display:flex;align-items:center;gap:10px;margin:4px 0 12px}
.chat .dayline::before{content:'';flex:1;height:1px;background:var(--rule)}
.chat .dayline span{flex:none;font-size:10px;letter-spacing:.1em;text-transform:uppercase;font-weight:600;color:var(--muted)}
.chat .dayline i{flex:1;height:1px;background:var(--rule)}
/* The foot: the line being answered, then the pill. No rule over it; the page runs under it. */
.chat .chatbox{flex:none;display:flex;padding:10px 12px;
  padding-bottom:max(16px, env(safe-area-inset-bottom));border-top:0;background:var(--page)}
.kb .chat .chatbox{padding-bottom:10px}
/* 16px because anything smaller makes iOS zoom the page when the field takes focus. The field is
   the middle of the pill: no fill and no edge of its own, and the focus ring goes round the pill. */
.chat .chatbox textarea{flex:1;min-width:0;font-size:16px;line-height:1.4;min-height:44px;max-height:120px;
  resize:none;padding:11px 4px;margin:0 4px 0 3px;overflow-y:auto;background:none;border:0;border-radius:0}
.chat .chatbox textarea:focus-visible{outline:0}
.chat .chatbox .row:has(textarea:focus){outline:2px solid var(--color-accent);outline-offset:2px}
/* Send: a 40px red disc, drawn inside a 44px target. */
.chat .sendsq{width:44px;height:44px;flex:none;display:grid;place-items:center;cursor:pointer;padding:0;
  border:2px solid transparent;border-radius:50%;background:var(--accent-fill);background-clip:padding-box;
  color:#fff;-webkit-tap-highlight-color:transparent}
.chat .sendsq svg{width:18px;height:18px;stroke-width:2.4}
.chat .sendsq.off{opacity:.45}
/* The composer is two rows now — the line being answered, then the field — so the row that used to
   be the whole of it is a row of its own and the box is a column. The row is the pill: 48 tall,
   the emoji button at its left, the field, the send at its right. */
.chat .chatbox{flex-direction:column;align-items:stretch;gap:8px}
.chat .chatbox .row{display:flex;align-items:flex-end;gap:0;min-height:48px;padding:2px 2px 2px 3px;
  border-radius:24px;background:var(--surface-1)}
.chat .trayb{width:44px;height:44px;flex:none;display:grid;place-items:center;padding:0;cursor:pointer;
  border:3px solid transparent;border-radius:50%;background:none;background-clip:padding-box;
  color:var(--text-2);-webkit-tap-highlight-color:transparent}
.chat .trayb svg{width:19px;height:19px}
.chat .trayb.on{background-color:var(--surface-3);color:var(--color-text)}

/* Anstupsen, from inside the conversation. It sits in the bar because it is about the person, not
   about anything that has been said. A round button on the surface; red once it has gone. */
.chat .nudgebtn{width:38px;height:38px;flex:none;display:grid;place-items:center;padding:0;border:0;border-radius:50%;
  background:var(--surface-1);color:var(--color-text);cursor:pointer;-webkit-tap-highlight-color:transparent}
.chat .nudgebtn.went{background:var(--accent-fill);color:#fff}
/* Pop out (a mouse, a browser tab): the same round button, drawn 38 inside a 44 hit. */
.chat .popbtn{width:44px;height:44px;flex:none;display:grid;place-items:center;padding:0;cursor:pointer;
  border:3px solid transparent;border-radius:50%;background:var(--surface-1);background-clip:padding-box;
  color:var(--color-text);margin:-3px -7px -3px -3px}
/* Which window (10.7.1): Always on top or a Normal window, under the button; the last one taken is
   ticked. The clear layer behind it takes the click that closes it. */
.chat .popwrap{position:relative;flex:none;display:flex}
.chat .popbtn.on{background-color:var(--surface-3)}
.chat .popback{position:fixed;inset:0;z-index:30}
.chat .popmenu{position:absolute;top:calc(100% + 6px);right:0;z-index:31;min-width:210px;padding:6px;
  display:flex;flex-direction:column;background:var(--surface-2);border-radius:14px;box-shadow:0 8px 28px rgba(0,0,0,.28)}
.chat .popmenu button{display:flex;align-items:center;gap:10px;min-height:44px;padding:0 12px;border:0;border-radius:10px;
  background:none;color:var(--color-text);font-size:14px;text-align:left;cursor:pointer}
.chat .popmenu button:hover{background:var(--surface-3)}
.chat .popmenu button span{flex:1}
.chat .popmenu button[aria-checked="true"]{font-weight:700}
/* The chat popped out into a window of its own: the person, the conversation, the field. Made for a
   window dragged down to a corner, so under 420 wide everything gives up its spare room and the
   field stays one line, scrolling inside itself. */
.chat.solo .bar{padding:6px 12px;gap:10px}
.chat.solo .bar .nm{font-size:15px}
.chat.solo .chatbox{padding-bottom:10px}
@media (max-width: 420px){
  .chat.solo .bar{padding:4px 10px;gap:8px}
  .chat.solo .msgs{padding:8px 8px 4px}
  .chat.solo .msg{max-width:88%;padding:7px 11px}
  .chat.solo .mwrap{max-width:90%}
  .chat.solo .run{margin-bottom:8px}
  .chat.solo .chatbox{padding:4px 6px 6px;gap:4px}
  .chat.solo .chatbox textarea{max-height:44px}
  .chat.solo .chattray{margin:0 6px;max-height:40vh}
  .chat.solo .chattray + .chatbox{margin:0 6px 6px}
}

/* A message and the line above it saying what it answers. The wrapper is what a long press lands
   on, so it carries the tap highlight and the flash a quote jumps to. */
.chat .mwrap{max-width:82%;display:flex;flex-direction:column;align-items:flex-start;gap:2px;
  -webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;user-select:none}
.chat .run.mine .mwrap{align-items:flex-end}
.chat .mwrap.lit .msg{outline:2px solid var(--color-accent);outline-offset:2px}
.chat .mwrap .msg{max-width:100%}
/* Being sent (10.8.0): drawn at once, faded, a small clock under it. Failed: full strength, with
   the line that sends it again. */
.chat .mwrap.sending > :not(.mstate){opacity:.55}
.chat .mstate{display:flex;align-items:center;gap:4px;font-size:11px;color:var(--muted);padding:0 4px}
.chat .mstate svg{width:11px;height:11px}
.chat .mstate.mretry{border:0;background:none;color:var(--accent-text);font:inherit;font-size:11px;
  min-height:28px;cursor:pointer}
/* Older pages load at the top; the browser's own scroll anchoring is off so the app's is the only one. */
.chat .msgs{overflow-anchor:none}
.chat .msgsmore{flex:none;height:28px;display:grid;place-items:center}
.chat .msgsmore i{width:16px;height:16px;border-radius:50%;border:2px solid var(--rule);border-top-color:var(--muted);
  animation:jrSpin .8s linear infinite}
@keyframes jrSpin{to{transform:rotate(360deg)}}
/* The quote over a bubble is the quote over the composer, smaller: a card, the name in the soft
   accent, the words muted. */
.chat .mquote{max-width:100%;display:flex;flex-direction:column;align-items:flex-start;gap:2px;text-align:left;
  padding:7px 12px;border:0;border-radius:14px;background:var(--surface-1);
  color:var(--color-text);cursor:pointer;font:inherit}
.chat .run.mine .mquote{background:var(--surface-1)}
.chat .mquote .who{font-size:10px;letter-spacing:.1em;text-transform:uppercase;font-weight:800;color:var(--accent-soft)}
.chat .mquote .what{font-size:12px;line-height:1.3;color:var(--muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}
/* A sticker and a gif are the message, not an attachment: no block behind them. */
.chat .msticker{width:104px;height:104px;object-fit:contain}
/* 10.7.0. Words can be selected and copied with a mouse (a finger's long press stays the hold that
   answers), and a link gets the phone's own menu rather than the hold's. */
@media (pointer: fine){ .chat .mwrap .msg{-webkit-user-select:text;user-select:text;cursor:text} }
.chat .msg a{color:inherit;text-decoration:underline;text-underline-offset:2px;-webkit-touch-callout:default;cursor:pointer}
/* A picture: the thumbnail, rounded like a bubble; a tap opens the whole of it. */
.chat .mphoto{display:block;border-radius:14px;overflow:hidden;background:var(--surface-1);line-height:0}
.chat .mphoto img{display:block;max-width:220px;max-height:260px;width:auto;height:auto}
/* The picture waiting over the field: small, with × and Send, so nothing goes out by accident. */
.chat .picchip{display:flex;align-items:center;gap:10px;padding:6px 6px 6px 8px;border-radius:14px;background:var(--surface-1)}
.chat .picchip img{width:44px;height:44px;flex:none;object-fit:cover;border-radius:8px}
.chat .picchip .what{flex:1;min-width:0;font-size:13px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.chat .picchip .x{flex:none;width:44px;height:44px;display:grid;place-items:center;padding:0;border:0;background:none;
  color:var(--text-2);cursor:pointer}
.chat .picchip .picsend{flex:none;height:44px;padding:0 16px;border:2px solid transparent;border-radius:22px;
  background:var(--accent-fill);background-clip:padding-box;color:#fff;font-weight:700;cursor:pointer}
/* "+": Photo and Camera, in a small menu over the field. */
.chat .plusb{width:44px;height:44px;flex:none;display:grid;place-items:center;padding:0;cursor:pointer;
  border:3px solid transparent;border-radius:50%;background:none;background-clip:padding-box;
  color:var(--text-2);-webkit-tap-highlight-color:transparent}
.chat .plusb.on{background-color:var(--surface-3);color:var(--color-text)}
.chat .chatplus{display:flex;gap:6px}
.chat .chatplus button{display:flex;align-items:center;gap:8px;min-height:44px;padding:0 14px;border:0;border-radius:22px;
  background:var(--surface-1);color:var(--color-text);font-size:14px;cursor:pointer}
.chat .mgif{max-width:220px;max-height:220px;object-fit:contain;background:var(--surface-1);border-radius:14px}

/* The line being answered, over the field: a card, the name in the soft accent, the words muted,
   and a way out. The spine that used to run down its side is not drawn any more. */
.chat .replying{display:flex;align-items:center;gap:8px;padding:8px 12px;border-radius:14px;background:var(--surface-1)}
.chat .replying .spine{display:none}
.chat .replying .body{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.chat .replying .who{font-size:10px;letter-spacing:.1em;text-transform:uppercase;font-weight:800;color:var(--accent-soft)}
.chat .replying .what{font-size:12px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.chat .replying .x{flex:none;width:34px;height:34px;margin:-6px -8px -6px 0;display:grid;place-items:center;border:0;
  border-radius:50%;background:none;color:var(--muted);cursor:pointer;padding:0}

/* The tray: emoji into the box, a sticker or a gif as its own message. It sits above the composer
   and inside the shell, never fixed — see the note on --vvh. Drawn with the composer under it as
   one card floating over the foot: the tray is its top, the composer (next sibling) its bottom,
   and the pill inside it a step up from the card. */
.chat .chattray{flex:none;margin:0 10px;border-top:0;border-radius:24px 24px 0 0;background:var(--surface-1);max-height:46vh;
  display:flex;flex-direction:column;overflow:hidden}
.chat .chattray + .chatbox{margin:0 10px max(14px, env(safe-area-inset-bottom));padding:2px 6px 6px;
  border-radius:0 0 24px 24px;background:var(--surface-1)}
.kb .chat .chattray + .chatbox{margin-bottom:10px}
.chat .chattray + .chatbox .row{background:var(--surface-2)}
/* On the page's own ground inside the card: the soft-accent name reads at 4.5:1 there and not on surface-2. */
.chat .chattray + .chatbox .replying{background:var(--page)}
.chat .chattray + .chatbox textarea::placeholder{color:var(--muted)}
/* The tabs are chips: the one showing is the light chip, the others bare. Drawn 28px inside the
   40px target they had before the restyle. Scoped to the chat: the journal's tabs are .ttabs too,
   and keep their own. */
.chat .ttabs{display:flex;align-items:center;gap:4px;padding:6px 6px 0;border-bottom:0;flex:none}
.chat .ttab{min-height:40px;margin:0;padding:0 12px;border:solid transparent;border-width:6px 3px;border-radius:17px/20px;background:none;
  background-clip:padding-box;cursor:pointer;font:inherit;font-family:var(--font-heading);font-size:11px;font-weight:800;
  line-height:1;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.chat .ttab.on{background-color:var(--sel-bg);color:var(--sel-fg);border-bottom-color:transparent;box-shadow:none}
.chat .tclose{margin-left:auto;width:36px;height:36px;display:grid;place-items:center;padding:0;cursor:pointer;
  border:2px solid transparent;border-radius:50%;background:var(--surface-2);background-clip:padding-box;color:var(--text-2)}
.chat .tclose svg{width:14px;height:14px;stroke-width:2.2}
.chat .tquick{display:grid;grid-template-columns:repeat(8,1fr);gap:2px;padding:6px 8px;overflow:auto}
/* 44 to hit, as before the restyle; what lights under a finger is the design's 40. */
.chat .tq{height:44px;display:grid;place-items:center;border:solid transparent;border-width:2px 0;border-radius:12px/14px;
  background:none;background-clip:padding-box;font-size:22px;
  cursor:pointer;-webkit-tap-highlight-color:transparent}
.chat .tq:active{background-color:var(--surface-2)}
.chat .tstick{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;padding:8px 10px;overflow:auto}
.chat .ts{aspect-ratio:1;display:grid;place-items:center;border:0;border-radius:14px;background:var(--surface-2);cursor:pointer;padding:6px}
.chat .ts img{width:100%;height:100%;object-fit:contain}
/* Your own stickers, in a row of their own above the shelf, sideways: the "+" that adds one, then
   them, newest first. */
.chat .tmine{display:flex;gap:8px;padding:8px 10px 0;overflow-x:auto;flex:none;scrollbar-width:none;touch-action:pan-x}
.chat .tmine::-webkit-scrollbar{display:none}
.chat .tmine button{flex:none;width:56px;height:56px;display:grid;place-items:center;border:0;border-radius:14px;
  background:var(--surface-2);color:var(--text-2);cursor:pointer;padding:6px}
.chat .tmine img{width:100%;height:100%;object-fit:contain}
.chat .tgif{display:flex;flex-direction:column;gap:8px;padding:8px 10px;overflow:hidden;min-height:0}
.chat .tgif .input{font-size:16px;min-height:44px;padding:0 16px;border-radius:22px;background-color:var(--surface-2);flex:none}
.chat .tgif .input::placeholder{color:var(--muted)}
.chat .ggrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px;overflow:auto;min-height:0}
.chat .gg{aspect-ratio:1;border:0;border-radius:12px;background:var(--surface-2);cursor:pointer;padding:0;overflow:hidden}
.chat .gg img{width:100%;height:100%;object-fit:cover;display:block}
.chat .gnone{grid-column:1/-1;padding:18px 0;text-align:center;font-size:12px;color:var(--muted)}
.chat .gerr{flex:none;padding:4px 0}
/* Rows as tall as their square cells. Left to auto, a row of aspect-ratio cells that clip their
   overflow was sized at 16px in Chromium, and every row after the first was drawn over the last. */
.chat .ggrid{grid-auto-rows:max-content}
.chat .gmark{padding:0 4px 2px}

/* Who has nudged you, over the chat list. Gone entirely when nobody has, which is most days. */
.nudgestrip{padding:10px 0 12px;margin:0 0 4px;
  background:linear-gradient(var(--rule),var(--rule)) center bottom / calc(100% - 36px) 1px no-repeat}
.nudgestrip .k{padding:0 18px 8px;font-size:10px;letter-spacing:.1em;text-transform:uppercase;font-weight:600;
  color:var(--muted)}
.nudgestrip .hscroll{display:flex;gap:10px;overflow-x:auto;padding:0 18px;scrollbar-width:none}
.nudgestrip .hscroll::-webkit-scrollbar{display:none}
.nudgeone{flex:none;width:84px;display:flex;flex-direction:column;align-items:center;gap:6px}
.nudgeone .who{position:relative;display:flex;flex-direction:column;align-items:center;gap:4px;border:0;background:none;
  cursor:pointer;padding:0;width:100%}
.nudgeone .nm{font-size:11px;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-text)}
.nudgeone .badge{position:absolute;top:-2px;right:14px;min-width:18px;height:18px;padding:0 5px;border-radius:9px;
  box-shadow:0 0 0 2px var(--page);background:var(--accent-fill);color:#fff;font-size:10px;font-weight:700;display:grid;place-items:center}
/* Filled, not outlined: a small secondary pill, red once the nudge has gone back. */
.nudgeone .back{width:100%;min-height:30px;padding:0 6px;border:0;border-radius:15px;background:var(--surface-1);
  color:var(--color-text);font:inherit;font-family:var(--font-heading);font-size:10px;font-weight:800;letter-spacing:.08em;
  text-transform:uppercase;cursor:pointer;-webkit-tap-highlight-color:transparent}
.nudgeone .back.went{background:var(--accent-fill);color:#fff}

/* ─── reminders ─────────────────────────────────────────────────────────── */
/* Every selector here is under .reminders. `.rnew` on its own was the unread badge on a journal
   row on Home, and an unscoped class in a sheet this size is a promise to collide with something
   eventually — that one turned a 16px badge into a padded column with a rule under it, and showed
   up a hundred pixels away as a spread that had grown.

   Softer since the restyle: filled controls with rounded corners, ruled rows that are never tiles,
   Archivo throughout, tabular figures on every time and date, and every label flush left —
   including inside a full-width button, where centring is the easy mistake. Accent is spent on the
   primary buttons (+ New on the list, the save on the form), a paused status and the random note's
   rule. Nothing else on this screen gets it, and in particular no label sits in a field of it: a
   red band carrying WHAT SHOULD IT SAY spends the system's one loud move on a form label. */
.reminders{display:flex;flex-direction:column}
.reminders .bar{padding:10px 14px 10px 18px;border-bottom:0;display:flex;align-items:center;gap:12px;flex:none}
/* 44px, and pulled back by half the padding so the glyph sits optically flush with the title. */
.reminders .bar .back{flex:none;width:44px;height:44px;margin-left:-11px;display:grid;place-items:center;
  border:0;background:none;color:var(--color-text);cursor:pointer;padding:0}
.reminders .bar .h1{flex:1;min-width:0;font-size:22px;line-height:1;letter-spacing:-.02em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* The only route to writing a reminder once the list has anything in it, so it is a full 44px and
   wears the accent: one action on the screen, said once. A red pill (it carries .btn-primary for
   its fill), drawn 38px tall inside the 44px target. */
.reminders .bar .new{flex:none;display:flex;align-items:center;gap:6px;min-height:44px;margin:0 -3px 0 0;padding:0 13px 0 9px;
  border:3px solid transparent;border-radius:22px;background-clip:padding-box;cursor:pointer;
  font:inherit;font-family:var(--font-heading);font-weight:800;font-size:11px;line-height:1;letter-spacing:.08em;text-transform:uppercase}
.reminders .bar .new svg{width:13px;height:13px;stroke-width:2.4}
.reminders .list{flex:1;overflow:auto;min-height:0;padding:0 0 24px}

/* the list */
.reminders .nextup{padding:10px 18px 4px;font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  font-weight:600;color:var(--muted)}
.reminders .rrow{display:flex;align-items:center;gap:6px;margin:0 18px;padding:10px 0;
  border-bottom:1px solid var(--rule)}
.reminders .rrow .body{flex:1;min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:8px;
  border:0;background:none;color:inherit;font:inherit;text-align:left;padding:0;cursor:pointer}
.reminders .rrow .t{font-family:var(--font-heading);font-weight:800;font-size:16px;line-height:1.2;
  letter-spacing:-.01em;overflow-wrap:anywhere}
/* padding:0 because the spread's own .meta (a tile's foot) carries 9px of it, and an unscoped
   class reaches this one too — it put 9px between the title and the chip. */
.reminders .rrow .meta{display:flex;align-items:baseline;gap:8px;width:100%;min-width:0;padding:0}
/* The rule, as a chip: the setting read back, short enough to sit beside the arrival. */
.reminders .rrow .every{flex:none;font-size:9px;line-height:11px;letter-spacing:.1em;text-transform:uppercase;font-weight:800;
  padding:4px 9px;border-radius:12px;background:var(--surface-1);color:var(--color-text)}
/* And the arrival, which is the thing the screen is opened to check. */
.reminders .rrow .at{flex:1;min-width:0;font-size:12px;line-height:1.35;color:var(--color-neutral-600);
  font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Under 340 the arrival is the thing the screen is opened to read, so it wraps rather than ends in
   an ellipsis beside the chip. */
@media (max-width:340px){.reminders .rrow .at{white-space:normal}}
/* Paused: the words and the chip go quiet, the status does not. Dimming the whole row drags a 12px
   line to about 4.3:1 against the ground, under the floor, and the status is the one thing on a
   paused row that has to be readable. */
.reminders .rrow.off .t, .reminders .rrow.off .every{opacity:.55}
.reminders .rrow.off .at{color:var(--color-accent-800)}
/* Pause and delete: 36px discs on the surface, each drawn inside a 44px target. The 4px of
   transparent edge is why the second one is pulled 2px in (6px apart as drawn) and the last one 4px
   out (flush with the gutter as drawn). */
.reminders .rrow .act{flex:none;width:44px;height:44px;display:grid;place-items:center;padding:0;cursor:pointer;
  border:4px solid transparent;border-radius:50%;background:var(--surface-1);background-clip:padding-box;
  color:var(--color-text)}
.reminders .rrow .act + .act{margin-left:-8px}
.reminders .rrow .act:last-child{margin-right:-4px}
.reminders .rrow .act svg{width:15px;height:15px}
.reminders .rrow .act.lit{color:var(--color-accent-800)}
.reminders .foot{padding:12px 18px 20px;font-size:11px;line-height:1.45;color:var(--color-neutral-600)}

/* nothing set */
.reminders .none{padding:26px 18px;text-align:left}
.reminders .none h2{margin:0;font-family:var(--font-heading);font-weight:800;font-size:26px;line-height:1.05;
  letter-spacing:-.03em;color:var(--color-text)}
.reminders .none p{margin:12px 0 0;font-size:14px;line-height:1.5;color:var(--color-neutral-700)}
.reminders .seedhd{margin-top:22px;padding:0 0 2px;border-top:0;
  font-size:10px;letter-spacing:.1em;text-transform:uppercase;font-weight:600;color:var(--color-neutral-600)}
/* A first reminder, one tap away: filled rows on the surface, as the design draws suggestions. */
.reminders .seed{display:flex;align-items:center;gap:10px;width:100%;min-height:52px;padding:0 14px;margin-top:6px;
  border:0;border-radius:14px;background:var(--surface-1);color:var(--color-text);font:inherit;cursor:pointer;text-align:left}
.reminders .seed .t{flex:1;min-width:0;font-size:14px;line-height:1.3}
.reminders .seed .every{flex:none;font-size:9px;letter-spacing:.1em;text-transform:uppercase;font-weight:600;
  color:var(--color-neutral-600)}

/* the form */
.reminders .sec{padding:16px 18px 0}
.reminders .sub{display:block;font-size:10px;letter-spacing:.12em;text-transform:uppercase;font-weight:600;
  color:var(--color-neutral-600)}
.reminders .subrule{display:flex;align-items:center;gap:8px;padding-bottom:0;border-bottom:0}
.reminders .sec .input{margin-top:8px;min-height:48px;width:100%;box-sizing:border-box;font-size:16px}
/* padding:0 because `.hint` on its own carries 16px of it, which put this line 16px to the
   right of the label it belongs under — flush left is the rule, and it is the one an
   inherited class breaks quietest. */
.reminders .hint{margin:7px 0 0;padding:0;font-size:11px;line-height:1.45;color:var(--color-neutral-600)}
.reminders .field{display:flex;align-items:center;gap:10px;margin-top:8px}
/* A native picker, sized like the box the design draws round it, with figures that line up. */
.reminders .field .input{flex:none;width:auto;margin-top:0;min-height:46px;padding:0 12px;
  font-family:var(--font-heading);font-weight:800;font-size:19px;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.reminders .field .say{flex:1;min-width:0;font-size:11px;line-height:1.4;color:var(--color-neutral-600)}
/* Three options as filled rows, the picked one the light chip, each with a round mark. */
.reminders .rkinds{display:flex;flex-direction:column;gap:6px;margin-top:8px}
.reminders .rkind{display:grid;grid-template-columns:auto minmax(0,1fr);gap:0 10px;width:100%;padding:12px 14px;
  border:0;border-radius:14px;background:var(--surface-1);color:var(--color-text);
  font:inherit;cursor:pointer;text-align:left}
.reminders .rkind .dot{grid-row:1;width:18px;height:18px;margin-top:2px;border:2px solid var(--muted);border-radius:50%;display:block}
.reminders .rkind .says{grid-row:1;min-width:0}
.reminders .rkind .nm{display:block;font-family:var(--font-heading);font-weight:800;font-size:16px;
  line-height:1.2;letter-spacing:-.01em}
/* Two lines by design: it is what lets "Turns up at an hour you cannot learn…" survive German. */
.reminders .rkind .how{display:block;margin-top:5px;font-size:12px;line-height:1.4;color:var(--color-neutral-600)}
.reminders .rkind.on{background:var(--sel-bg);color:var(--sel-fg)}
.reminders .rkind.on .dot{border-color:var(--sel-fg);background:var(--sel-fg)}
.reminders .rkind.on .how{color:var(--color-neutral-300)}
/* The one place accent is a rule rather than a fill: the note that stands in for a missing field. */
/* The note that stands in for a missing field: a card on the accent's tint rather than a red rule
   down its side, which was the old language's one way of saying "read this". */
.reminders .rnote{margin:18px 18px 0;padding:11px 14px;border:0;border-radius:var(--radius-md);background:var(--accent-tint);
  font-size:13px;line-height:1.5;color:var(--color-text)}
/* Ink, not accent: this is a statement of fact, not the action. A card on the surface, no rail. */
.reminders .first{display:flex;align-items:baseline;gap:9px;margin:20px 18px 0;padding:12px 14px;
  border:0;border-radius:var(--radius-md);background:var(--surface-1)}
.reminders .first .k{flex:none;font-size:10px;letter-spacing:.1em;text-transform:uppercase;font-weight:600;
  color:var(--muted)}
.reminders .first .v{flex:1;min-width:0;font-size:13px;line-height:1.4;font-weight:500;font-variant-numeric:tabular-nums}
.reminders .acts{padding:16px 18px 24px}
/* Flush left, inside the button too — the one rule this screen kept getting wrong. */
.reminders .acts .save{min-height:50px;justify-content:flex-start;text-align:left}
.reminders .acts .drop{display:flex;align-items:center;gap:8px;width:100%;min-height:46px;margin-top:8px;padding:0 14px;
  border:0;border-radius:14px;background:var(--surface-1);color:var(--accent-text);cursor:pointer;text-align:left;
  font:inherit;font-family:var(--font-heading);font-weight:800;font-size:11px;letter-spacing:.1em;text-transform:uppercase}

/* ─── me ────────────────────────────────────────────────────────────────── */
/* One quiet list. Every selector is under .me.

   The screen was six sections, four of them with a paragraph under the head, and a full-width
   accent button in the middle. What replaces all of it is one row shape — symbol, name, what it
   says now, chevron — and, where there is a choice, two 44×44 cells inside an ink border. Three
   group labels with no rule under them: the 2px rule is the strongest horizontal mark this app
   has, and six of them on one screen is most of what made it loud. */
.me .top{padding:18px 14px 8px 18px;display:flex;align-items:center;gap:14px}
/* 60px and round, with a badge where every phone puts it, ringed in the page so it sits clear of
   the face. No ink edge any more: the softer design separates by surface, not by rule. */
.me .mephoto{flex:none;position:relative;width:60px;height:60px;box-sizing:border-box;padding:0;cursor:pointer;
  border:0;border-radius:50%;background:var(--surface-1);display:block}
.me .mephoto .meav{width:100%;height:100%;font-size:24px;border-radius:50%}
.me .mephoto .badge{position:absolute;right:-3px;bottom:-3px;width:22px;height:22px;display:grid;place-items:center;
  border-radius:50%;background:var(--color-text);color:var(--color-bg);box-shadow:0 0 0 2px var(--page)}
.me .top .who{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.me .top .h1{margin:0;font-size:22px;line-height:1.1;letter-spacing:-.02em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Ellipsised, because a long address must not push the two switches off the row. */
.me .top .email{margin-top:0;font-size:12px;color:var(--muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Language and theme: one pill of two cells. Neither is filled with accent — a preference is not
   the one loud thing on a screen, and the theme button used to be. Each cell is still 44px to hit. */
.me .sqs{flex:none;display:flex;border:0;border-radius:22px;background:var(--surface-1)}
.me .sqs .sq{width:44px;height:44px;flex:none;padding:0;display:grid;place-items:center;cursor:pointer;
  border:0;border-radius:22px;background:none;color:var(--color-text);
  font-family:var(--font-heading);font-weight:800;font-size:12px;letter-spacing:.06em}
.me .sqs .sq svg{width:16px;height:16px}

/* the groups, and the rows under them. A row is the whole width to hit; its rule is drawn inside
   the 18px gutter, as a background band, so the target does not shrink with it. */
.me .grp{padding:14px 18px 4px;font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  font-weight:600;color:var(--muted)}
.me .grp.first{padding-top:14px}
.me .merow{display:flex;align-items:center;gap:12px;width:100%;min-height:50px;padding:0 18px;
  border:0;background:linear-gradient(var(--rule),var(--rule)) center bottom / calc(100% - 36px) 1px no-repeat;
  color:var(--color-text);font:inherit;text-align:left;cursor:pointer}
.me .merow.flat{cursor:default}
.me .merow.pick{padding:3px 18px}
.me .merow .ico{flex:none;display:grid}
.me .merow .ico svg{width:19px;height:19px}
.me .merow .nm{flex:1;min-width:0;font-family:var(--font-heading);font-weight:800;font-size:15px;
  letter-spacing:-.01em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* The right edge answers "is anything waiting for me" without opening anything. It is the thing
   that lets the descriptions go, so it is never lighter than -700: at 10px, -600 measures about
   3.85:1 in light and -400 about 1.8:1. */
.me .merow .val{flex:none;font-size:10px;letter-spacing:.1em;text-transform:uppercase;font-weight:800;
  color:var(--muted);font-variant-numeric:tabular-nums}
.me .merow .val.lit{color:var(--color-accent-800)}
.me .merow .chev{flex:none;display:grid;color:var(--muted)}
.me .merow .chev svg{width:14px;height:14px}
/* Under 340 a row's title had what the switch and the value left it: "Njo…" in Albanian, "Mitteilun…"
   in German. There the value goes under the title, so the title has the row's whole middle. */
@media (max-width:340px){
  .me .merow:has(> .val){display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:0 12px;align-content:center}
  .me .merow:has(> .val) .ico{grid-column:1;grid-row:1/3;align-self:center}
  .me .merow:has(> .val) .nm{grid-column:2;grid-row:1}
  .me .merow:has(> .val) .val{grid-column:2;grid-row:2;justify-self:start;margin-top:2px}
  .me .merow:has(> .val) .chev,.me .merow:has(> .val) .two{grid-column:3;grid-row:1/3;align-self:center}
}
/* Two cells on one track: the filled one is where you are, the empty one is what tapping it does.
   A single button can only ever say one of those two, and it always says the action. Drawn as the
   design draws it — a 74×34 track, r18, and the light segment 34×28, r14, 3px inside it — while each
   cell is still 44×44 to hit. The track is the content box of an 88×44 box (padding 5/7, the fill
   clipped to it), the cells reach back over that padding with their margins, and each segment is
   its cell's padding box: a clear edge 8px above and below and 10px on the outer side. */
.me .two{flex:none;display:flex;padding:5px 7px;border:0;border-radius:25px/23px;
  background:var(--surface-1);background-clip:content-box}
.me .two .cell{width:44px;height:44px;margin:-5px 0;display:grid;place-items:center;padding:0;cursor:pointer;
  border:solid transparent;border-width:8px 0 8px 10px;border-radius:24px 14px 14px 24px/22px;
  background:none;background-clip:padding-box;color:var(--placeholder)}
.me .two .cell:first-child{margin-left:-7px}
.me .two .cell:last-child{margin-right:-7px;border-width:8px 10px 8px 0;border-radius:14px 24px 24px 14px/22px}
.me .two .cell.on{background-color:var(--sel-bg);color:var(--sel-fg)}
.me .two .cell:disabled{opacity:.55;cursor:default}
/* The one sentence left on the screen, and the two lines that only appear when something is
   wrong. Flush left with the rows they sit under. */
.me .say{padding:10px 18px 0;font-size:11px;line-height:1.45;color:var(--muted)}
.me .say.under{padding-bottom:2px}
.me .err{padding:10px 18px 0;font-size:11px;line-height:1.45;color:var(--color-accent-800)}
/* A test push is an action, not a setting, so it is not a row: one quiet flush-left button under
   the control it belongs to. */
.me .thin{display:flex;align-items:center;min-height:44px;padding:0 18px;border:0;background:none;
  color:var(--color-neutral-700);cursor:pointer;font:inherit;font-family:var(--font-heading);
  font-weight:600;font-size:11px;letter-spacing:.1em;text-transform:uppercase;text-align:left}
.me .thin:disabled{opacity:.55}

/* the foot: two buttons side by side, and what this phone is running */
.me .band{display:flex;align-items:center;gap:0;padding:13px 15px 5px;margin-top:0;border-top:0}
/* Signing out is not destructive, so it does not get the app's one loud colour. It used to.
   A secondary pill, drawn 38px tall inside the 44px it is to hit; the 3px of transparent edge
   round each is also what spaces the two 6px apart and lines them up with the gutter. */
.me .band .pill{flex:none;display:flex;align-items:center;gap:8px;min-height:44px;padding:0 13px 0 9px;
  border:3px solid transparent;border-radius:22px;background:var(--surface-1);background-clip:padding-box;
  color:var(--color-text);cursor:pointer;
  font:inherit;font-family:var(--font-heading);font-weight:800;font-size:11px;
  letter-spacing:.08em;text-transform:uppercase;text-align:left}
.me .band .pill svg{width:14px;height:14px}

/* the feedback form, under the row that opens it */
.me .fbform{display:grid;gap:12px;padding:12px 18px}
.me .fbform .btn{margin:0}
.me .fbform .btn svg{margin-left:auto}
.me .sub{font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;
  color:var(--muted);margin-bottom:6px}
.me .fbtext{font-size:16px;min-height:104px;line-height:1.4;resize:vertical}
.me .fbform .err{padding:0;font-size:13px}
/* Accent fills the primary button and nothing else, here as everywhere. Cancelling a form and
   closing a sheet are not the loud thing on the screen — they used to be drawn as though they
   were, which is the same mistake Sign out was making one section down. */
.me .fbform .btn-ghost, .mesheet .sheet-foot .btn-ghost{color:var(--color-text)}

/* The version line is flush left here like every other label on this screen. It is centred
   wherever else it appears — the intro's foot — and .build is shared, so Me says so itself. */
.me .build{padding:4px 18px 22px;text-align:left;font-size:10px;line-height:1.6;color:var(--placeholder)}
.me .build button{margin:8px 0 0}
.me .build .rights{margin-top:0;font-size:10px;letter-spacing:0;color:var(--placeholder)}

/* the install sheet: the how, wanted once, by somebody who has already decided */
/* Drawn as the other sheets are: the title at the sheet size, the how in the secondary ink, the one
   red Install, and Close a filled row rather than a red word under a 2px rule. */
.mesheet .sheet-body{padding:21px 18px 8px;gap:12px}
.mesheet .sheet-body p{margin:0;font-size:14px;line-height:1.5;color:var(--text-2)}
.mesheet .sheet-body .h2{margin:0;font-family:var(--font-heading);font-weight:800;font-size:24px;line-height:1.1;letter-spacing:-.02em}
.mesheet .sheet-body .btn{margin:4px 0 0;border-radius:var(--radius-md);font-weight:800}
.mesheet .sheet-foot{padding:6px 18px 14px;border:0}
.mesheet .sheet-foot .btn{min-height:48px;padding:0 16px;border-radius:var(--radius-md);background:var(--surface-1);font-weight:800}
/* ─── feedback: the form in Me, the inbox for the admin ─────────────────── */
/* The All / New filter on the inbox. Me used this for Theme and Language until each became one
   square button, so the inbox is the only place left that segments anything. */
/* A track on the surface and a light segment for the one you are on, drawn inside the 44px cell. */
.seg{display:flex;border:0;width:100%;border-radius:22px;background:var(--surface-1)}
.seg button{flex:1;min-height:44px;border:4px solid transparent;border-radius:22px;background:transparent;background-clip:padding-box;color:var(--text-2);font:inherit;font-size:13px;font-weight:800;cursor:pointer;text-align:left;padding:0 10px}
.seg button.on{background-color:var(--sel-bg);color:var(--sel-fg)}
/* Me's own rules for the form live in the me block above — the admin inbox below is the only
   thing left down here, and .seg is the only segmented control left in the app. */

/* The inbox is a browse screen: no rules under its bars, the filter a track inside the 18px gutter,
   and every piece of feedback a row on a 1px rule. Its screen is a small filled chip rather than a
   tilted ink label; new is the round accent badge the rest of the app counts with. */
.feedback .bar,.monitoring .bar{padding:10px 7px 10px 7px;border-bottom:0;gap:8px}
.feedback .bar .h1,.monitoring .bar .h1{flex:1;min-width:0;font-size:22px;letter-spacing:-.02em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.feedback .subbar{display:flex;align-items:center;gap:8px;padding:2px 18px 10px;border:0;flex:none}
.feedback .subbar .seg{flex:1;width:auto}
.feedback .subbar .seg button{text-align:center;min-height:44px;font-size:13px}
.feedback .copyall{flex:none;min-height:44px;border-radius:var(--radius-md);font-weight:800;gap:6px}
.feedback .list{flex:1;padding:0 18px 24px}
.feedback .none{padding:32px 0;font-size:14px;line-height:1.5;color:var(--muted);max-width:34ch}
.feedback .err{padding:16px 0;font-size:13px;color:var(--accent-text)}
.fbrow{padding:14px 0 16px;border-bottom:1px solid var(--rule)}
.fbrow.read{opacity:.62}
.fbrow .head{display:flex;align-items:center;gap:12px}
.fbrow .who{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px;line-height:1.25}
.fbrow .who b{font-family:var(--font-heading);font-weight:800;font-size:15px}
.fbrow .who span{font-size:12px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.fbrow .new{background:var(--accent-fill);color:#fff;border-radius:10px;font-family:var(--font-heading);font-weight:800;font-size:9px;letter-spacing:.1em;text-transform:uppercase;padding:4px 8px;flex:none}
.fbrow .meta{display:flex;align-items:center;gap:8px;margin-top:10px;padding:0;font-size:10px;letter-spacing:.1em;text-transform:uppercase}
.fbrow .meta .src{background:var(--surface-1);color:var(--text-2);border-radius:12px;font-family:var(--font-heading);font-weight:800;padding:5px 9px}
.fbrow .meta .at{color:var(--muted);letter-spacing:0;text-transform:none;font-size:12px}
.fbrow .msg{margin:10px 0 0;font-size:15px;line-height:1.45;overflow-wrap:anywhere;white-space:pre-wrap}
.fbrow .acts{display:flex;flex-wrap:wrap;gap:6px;margin-top:12px}
.fbrow .acts .btn{min-height:40px;border-radius:20px;font-weight:800;font-size:12px}
.fbrow .acts .btn-secondary{padding:0 12px}
.fbrow .acts .btn svg{margin-right:2px}

/* ─── create journal ────────────────────────────────────────────────────── */
/* A form in the design's language: the 18px gutter, section labels in the small capitals, space
   between sections rather than 2px rules, and every choice a filled tile. The type you are making
   is the one red fill on the screen besides Create — it is the answer that decides the rest. */
.create .bar .h1{flex:1;font-size:22px;letter-spacing:-.02em}
.create .sec{padding:14px 18px 6px}
.create .sec .k{font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin:0 0 10px}
.types{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.types button{min-height:64px;padding:12px 14px;text-align:left;border:0;border-radius:var(--radius-md);background:var(--surface-1);color:var(--text);font:inherit;cursor:pointer;display:flex;flex-direction:column;justify-content:space-between;gap:4px}
.types button b{font-family:var(--font-heading);font-weight:800;font-size:15px}
.types button span{font-size:12px;color:var(--muted);line-height:1.3}
/* The deeper red in both themes: the line under the name is 12px white, 4.2:1 on #ec3013 and 5.1 here. */
.types button.on{background:#d42a10;color:var(--on-accent)}
.types button.on span{color:var(--on-accent)}
.create .namesec{display:grid;grid-template-columns:96px 1fr;gap:14px;align-items:start}
.create .coverslot{position:relative;aspect-ratio:3/4;background:var(--surface-1);border-radius:var(--radius-md);overflow:hidden;cursor:pointer}
.create .coverslot .media-box{position:absolute;inset:0}
/* "Someone else's journal" — the way into Join from Create: a filled row, its tag a small chip. */
.joinrow{margin-top:8px;width:100%;min-height:56px;padding:10px 14px;text-align:left;border:0;border-radius:var(--radius-md);background:var(--surface-1);color:var(--text);font:inherit;cursor:pointer;display:flex;align-items:center;gap:12px}
.joinrow .jrnl{background:var(--sel-bg);color:var(--sel-fg);font-family:var(--font-heading);font-weight:800;font-size:10px;letter-spacing:.1em;padding:5px 8px;border-radius:var(--radius-sm);flex:none}
.joinrow .txt{flex:1;display:flex;flex-direction:column;gap:2px;min-width:0}
.joinrow .txt b{font-family:var(--font-heading);font-weight:800;font-size:15px}
.joinrow .txt span{font-size:12px;color:var(--muted)}
.joinrow>svg{color:var(--muted)}
.create .note{font-size:12px;color:var(--muted);margin-bottom:10px}
.create .note.after{margin:10px 0 0}
.ruleparam{display:flex;gap:6px;margin-top:8px;align-items:center}
.ruleparam .input{min-height:44px;flex:1}
.ruleparam span{font-size:12px;color:var(--muted)}

/* ─── boot / errors ─────────────────────────────────────────────────────── */
.boot{flex:1;display:grid;place-items:center;color:var(--color-neutral-600);font-size:12px;letter-spacing:.1em;text-transform:uppercase}
.boot.err{color:var(--color-accent-800);text-transform:none;letter-spacing:0;padding:24px;text-align:center;font-size:14px;line-height:1.5}

/* ─── monitoring: the operations log ────────────────────────────────────── */
/* Admin only. Every row is an operation, never its contents. One column of red — the durations at
   or over a second — so that a pass down the right edge finds the slow work without reading. */
.monitoring .bar .h1{flex:1}
.oplist{flex:1;overflow:auto;min-height:0}
/* ─── monitoring: chrome ─────────────────────────────────────────────────── */
/* The screen nav scrolls sideways and never shrinks to fit. Six items do not cross 358px in
   German and never will, and an overflow menu hides exactly the screen somebody is looking for. */
.monitoring .head{flex:none;padding:10px 18px 0 7px;display:flex;align-items:center;gap:8px}
.monitoring .head .h1{flex:1;min-width:0;font-size:22px;line-height:1;letter-spacing:-.02em;margin:0}
.monitoring .asof{flex:none;font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);font-variant-numeric:tabular-nums}
/* The screens are the journal's tab chips, in a row that scrolls: drawn 34, hit 44. The window is a
   segmented track inside the gutter, the light segment the one being read. */
.opnav{flex:none;display:flex;gap:6px;margin-top:6px;padding:0 18px;overflow-x:auto;border:0;scrollbar-width:none}
.opnav::-webkit-scrollbar{width:0;height:0}
.opnav button{flex:none;position:relative;min-height:44px;padding:0 13px;margin:0;border:solid transparent;border-width:5px 0;border-radius:14px/19px;
  background-color:var(--surface-1);background-clip:padding-box;color:var(--text-2);font-family:var(--font-heading);font-weight:800;font-size:13px;cursor:pointer;white-space:nowrap}
.opnav button.on{background-color:var(--sel-bg);color:var(--sel-fg)}
/* The only navigation-level use of accent: something is still wrong. */
.opnav button i{position:absolute;top:4px;right:4px;width:7px;height:7px;border-radius:50%;background:var(--color-accent);box-shadow:0 0 0 2px var(--page);display:block}
.opwin{flex:none;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));margin:6px 18px 4px;border:0;border-radius:22px;background:var(--surface-1)}
.opwin button{min-height:44px;padding:0 4px;border:4px solid transparent;border-radius:22px;background:transparent;background-clip:padding-box;color:var(--text-2);
  font-family:var(--font-heading);font-weight:800;font-size:10px;letter-spacing:.04em;line-height:1.1;text-transform:uppercase;cursor:pointer;
  white-space:normal;overflow:hidden}
.opwin button.on{background-color:var(--sel-bg);color:var(--sel-fg)}
/* ─── monitoring: sections ───────────────────────────────────────────────── */
.opsec{padding:18px;border-bottom:1px solid var(--rule)}
.opsec.flush{padding:18px 18px 0}
.opk{display:flex;align-items:center;gap:8px;margin-bottom:12px}
.opk span{font-size:10px;letter-spacing:.1em;text-transform:uppercase;font-weight:600;color:var(--muted)}
.opk i{flex:1;height:1px;background:var(--rule);font-style:normal}
.opk .sort{flex:none;min-height:32px;padding:0 11px;border:0;border-radius:16px;background:var(--surface-1);color:var(--text-2);
  font:inherit;font-size:10px;letter-spacing:.08em;text-transform:uppercase;font-weight:800;cursor:pointer}
/* The comparison pattern, built once: a figure that cannot be shown without its baseline. */
.opfig{font-family:var(--font-heading);font-weight:800;font-size:36px;line-height:.92;letter-spacing:-.035em;font-variant-numeric:tabular-nums}
.opfig.mid{font-size:30px;line-height:.95}
.opfig.sm{font-size:24px;line-height:1;letter-spacing:-.03em}
.opcmp{margin-top:7px;font-size:12px;line-height:1.4;color:var(--color-neutral-600)}
.opcmp b{font-weight:600;color:var(--color-text)}
.opcmp b.bad{color:var(--color-accent-800)}
.opnote{margin-top:7px;font-size:11px;line-height:1.45;color:var(--color-neutral-600)}
.oppair{display:flex;align-items:flex-end;gap:16px}
.oppair > div + div{padding-left:16px;border-left:1px solid var(--color-divider)}
.oppair .lbl{margin-top:6px;font-size:12px;line-height:1.3;color:var(--color-neutral-600)}
/* ─── monitoring: charts ─────────────────────────────────────────────────── */
/* Flat rectangles standing on a rule. Every bar is a button, because a chart shows a shape and a
   reader who wants the number should not have to estimate it off a baseline. */
/* A chart is a plot with a scale on it and an axis under it — not a row of bars between two words.
   The rule across the top carries the maximum, so a height converts to a number by eye; the ticks
   under it carry about five times, so a spike can be placed. */
/* The inline height is the *bars'* height, so a bar's pixels mean what the scale says they mean.
   content-box keeps the room the scale label needs out of that number. */
.opplot{position:relative;box-sizing:content-box;padding-top:13px}
/* The scale, on the rule it means. Dashed so it cannot be mistaken for a bar or for the baseline. */
.optop{position:absolute;left:0;right:0;top:11px;border-top:1px dashed var(--color-neutral-400);pointer-events:none}
.optop b{position:absolute;right:0;top:-13px;font-size:10px;font-weight:700;letter-spacing:.06em;
  color:var(--color-neutral-600);background:var(--color-bg);padding-left:5px;font-variant-numeric:tabular-nums}
.opchart{position:absolute;left:0;right:0;bottom:0;top:13px;display:flex;align-items:flex-end;gap:2px;
  border-bottom:1px solid var(--color-text)}
.opchart button{flex:1;min-width:0;display:flex;align-items:flex-end;height:100%;border:0;padding:0;background:none;cursor:pointer;
  -webkit-tap-highlight-color:transparent}
.opchart button span{width:100%;min-height:1px;background:var(--color-text);display:block}
.opchart button span.nil{background:var(--color-divider)}
.opchart button span.bad{background:var(--color-accent)}
/* The column a bar stands in, tinted to say which one is being read. Mixed from the ink rather than
   taken from the neutral scale, because that scale inverts with the theme and a highlight that is
   *darker* than its ground in one theme and lighter in the other reads as a second bar. At this
   height a solid neutral slab did exactly that. */
.opchart button:hover{background:color-mix(in srgb, var(--color-text) 7%, transparent)}
.opchart button.on{background:color-mix(in srgb, var(--color-text) 12%, transparent)}
/* Selecting one drops the others back, so the chosen bar is the one being read. */
.opplot.picked .opchart button:not(.on) span{background:var(--color-neutral-400)}
/* The number over the bar it belongs to, not under the whole chart. */
.opread{position:absolute;z-index:2;display:flex;align-items:baseline;gap:6px;white-space:nowrap;
  padding:4px 8px;border:0;border-radius:var(--radius-sm);background:var(--surface-2);pointer-events:none}
.opread b{font-family:var(--font-heading);font-weight:800;font-size:14px;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.opread span{font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--text-2);font-variant-numeric:tabular-nums}
.opread.bad{box-shadow:0 0 0 2px var(--color-accent)}
.opread.bad b{color:var(--color-accent-800)}
/* The axis: a tick under each labelled bar, so a label points at something rather than floating. */
.opaxis{position:relative;height:26px}
.opaxis span{position:absolute;top:0;font-size:10px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--color-neutral-600);font-variant-numeric:tabular-nums;white-space:nowrap;padding-top:6px}
.opaxis span i{position:absolute;top:0;left:50%;width:1px;height:4px;background:var(--color-neutral-400);display:block}
.opaxis span:first-child i{left:0}
.opaxis span:last-child i{left:auto;right:0}
.opaxis span.on{color:var(--color-text);font-weight:700}
.opaxis span.on i{background:var(--color-text);height:6px}
.opsub{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
.opsub .n{font-size:11px;letter-spacing:.08em;text-transform:uppercase;font-weight:600}
.opsub .n b{font-family:var(--font-heading);font-weight:800;font-size:17px;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.opsub .n b.bad{color:var(--color-accent-800)}
.opsub .p{font-size:10px;letter-spacing:.06em;text-transform:uppercase;color:var(--color-neutral-600);font-variant-numeric:tabular-nums}
/* A pass/fail strip is not a magnitude, so it has no baseline rule. */
.opcheck{display:flex;gap:2px;height:22px}
.opckread{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin-top:8px;padding-top:7px;border-top:1px solid var(--color-text)}
.opckread .w{flex:none;font-size:10px;letter-spacing:.1em;text-transform:uppercase;font-weight:600;color:var(--color-neutral-600)}
.opckread .v{flex:1;min-width:0;text-align:right;font-size:13px;font-weight:600}
.opckread .v.bad{color:var(--color-accent-800)}
.opckends{display:flex;justify-content:space-between;gap:8px;margin-top:6px;font-size:10px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--color-neutral-600);font-variant-numeric:tabular-nums}
.opcheck button{flex:1;min-width:0;height:100%;border:0;padding:0;background:var(--color-text);cursor:pointer}
.opcheck button.bad{background:var(--color-accent)}
.opcheck button.nil{background:var(--color-divider)}
.opcheck button:hover{opacity:.65}
/* ─── monitoring: rows ───────────────────────────────────────────────────── */
.opkind{padding:9px 0 10px;border-bottom:1px solid var(--color-divider)}
.opkind .r{display:flex;align-items:baseline;gap:10px}
.opkind .k{flex:1;min-width:0;font-size:13px;line-height:1.3}
.opkind .n{flex:none;font-size:13px;font-weight:600;font-variant-numeric:tabular-nums}
/* Proportional to the largest row, never to the total: nobody reads a share-of-total bar at 3px. */
.opmeter{display:block;margin-top:7px;height:4px;border-radius:2px;overflow:hidden;background:var(--surface-2)}
.opmeter i{display:block;height:4px;border-radius:2px;background:var(--color-text)}
/* A kind people open and do not finish. The accent is the one thing on this screen that means
   "go and look at this", so it is spent on the rows that are actually a problem and nowhere else. */
.opkind .n.bad{color:var(--accent-text)}
.opmeter i.bad{background:var(--color-accent)}
/* A meter at zero is still a row worth seeing: a hairline says "measured, and it is none" where an
   empty track says nothing at all. */
.opmeter i{min-width:2px}
.opmore{margin-top:12px;min-height:44px;width:100%;border:0;border-radius:var(--radius-md);background:var(--surface-1);color:var(--text);
  font-family:var(--font-heading);font-weight:800;font-size:11px;letter-spacing:.08em;text-transform:uppercase;text-align:left;padding:0 14px;cursor:pointer}
.optype{display:flex;align-items:baseline;gap:10px;padding:8px 0;border-bottom:1px solid var(--color-divider)}
.optype .n{flex:none;font-family:var(--font-heading);font-weight:800;font-size:15px;letter-spacing:-.02em;font-variant-numeric:tabular-nums;min-width:52px}
.optype .k{flex:1;min-width:0;font-size:13px;line-height:1.3}
.optype .p{flex:none;font-size:11px;color:var(--color-neutral-600);font-variant-numeric:tabular-nums}
.opchange{display:flex;align-items:baseline;gap:10px;padding:10px 0;border-bottom:1px solid var(--color-divider)}
.opchange .a{flex:none;width:16px;font-family:var(--font-heading);font-weight:800;font-size:14px}
.opchange .a.bad{color:var(--color-accent-800)}
.opchange .t{flex:1;min-width:0;font-size:13px;line-height:1.35}
.opslower{padding:11px 0;border-bottom:1px solid var(--color-divider)}
.opslower .r{display:flex;align-items:baseline;gap:10px}
.opslower .k{flex:1;min-width:0;font-size:14px;line-height:1.35;font-weight:500}
.opslower .x{flex:none;font-family:var(--font-heading);font-weight:800;font-size:16px;letter-spacing:-.02em;
  color:var(--color-accent-800);font-variant-numeric:tabular-nums}
.opslower .d{margin-top:5px;font-size:11px;color:var(--color-neutral-600);font-variant-numeric:tabular-nums}
.opgrid{display:grid;grid-template-columns:minmax(0,1fr) 48px 52px;gap:2px 8px;align-items:baseline;padding:9px 0;border-bottom:1px solid var(--color-divider)}
.opgrid.hd{gap:0 8px;padding:0 0 7px;border-bottom:1px solid var(--color-text);font-size:9px;letter-spacing:.1em;text-transform:uppercase;
  font-weight:600;color:var(--color-neutral-600)}
.opgrid .k{font-size:13px;line-height:1.3}
.opgrid .a{font-size:12px;text-align:right;font-variant-numeric:tabular-nums;color:var(--color-neutral-700)}
.opgrid .b{font-size:13px;text-align:right;font-variant-numeric:tabular-nums}
.opgrid .b.bad{font-weight:700;color:var(--color-accent-800)}
.opgrid .c{grid-column:1;font-size:11px;color:var(--color-neutral-600);font-variant-numeric:tabular-nums}
.opgrid.hd span:not(:first-child){text-align:right}
/* An incident, not one row per occurrence. */
.opbad{padding:11px 0;border-bottom:1px solid var(--color-divider)}
.opbad .r{display:flex;align-items:baseline;gap:9px}
.opbad .n{flex:none;font-family:var(--font-heading);font-weight:800;font-size:15px;letter-spacing:-.02em;
  color:var(--color-accent-800);font-variant-numeric:tabular-nums}
.opbad .what{flex:1;min-width:0;font-size:14px;font-weight:600;line-height:1.3;overflow-wrap:anywhere}
.opbad .where{margin-top:5px;font-size:11px;line-height:1.4;color:var(--color-neutral-700);overflow-wrap:anywhere}
.opbad .when{margin-top:3px;font-size:11px;color:var(--color-neutral-600);font-variant-numeric:tabular-nums}
.opbad .tags{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 8px;margin-top:6px}
.opbad .agent{flex:none;white-space:nowrap;font-size:10px;letter-spacing:.08em;text-transform:uppercase;font-weight:600;
  padding:4px 8px;border:0;border-radius:10px;background:var(--surface-1);color:var(--text-2)}
.opok{display:flex;align-items:center;gap:10px;padding:4px 0 2px}
.opok i{flex:none;width:9px;height:9px;border-radius:50%;background:var(--color-text);display:block}
.opok span{font-size:14px;line-height:1.4;font-weight:500}
.opalert{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:4px 10px;padding:10px 0 10px 10px;
  border-bottom:1px solid var(--color-divider);border-left:3px solid var(--color-divider)}
.opalert.live{border-left-color:var(--color-accent)}
.opalert .w{font-size:13px;line-height:1.35;font-weight:500}
.opalert .s{flex:none;font-size:9px;letter-spacing:.1em;text-transform:uppercase;font-weight:700;white-space:nowrap;color:var(--color-neutral-600)}
.opalert.live .s{color:var(--color-accent-800)}
.opalert .when{grid-column:1/-1;font-size:11px;color:var(--color-neutral-600);font-variant-numeric:tabular-nums}
.opquota{display:block;margin-top:12px;height:8px;border-radius:4px;overflow:hidden;background:var(--surface-2)}
.opquota i{display:block;height:8px;border-radius:4px;background:var(--color-text)}
.opfunnel .v{flex:none;font-family:var(--font-heading);font-weight:800;font-size:22px;letter-spacing:-.03em;
  font-variant-numeric:tabular-nums;min-width:64px}
.opfunnel .r{display:flex;align-items:baseline;gap:10px;padding:9px 0;border-bottom:1px solid var(--color-divider)}
.opfunnel .k{flex:1;min-width:0;font-size:12px;letter-spacing:.08em;text-transform:uppercase;font-weight:600;line-height:1.3}
.opfunnel .drop{padding:7px 0 7px 18px;font-size:11px;line-height:1.35;color:var(--color-neutral-600)}
/* ─── monitoring: who's here ─────────────────────────────────────────────── */
.opwho{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));margin:0 -18px}
.opwho .cell{padding:12px 12px 14px;border-left:1px solid var(--color-divider)}
.opwho .cell b{display:block;font-family:var(--font-heading);font-weight:800;font-size:24px;line-height:1;letter-spacing:-.03em;
  font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
/* The kicker sits under its figure and wraps, which is what lets a German label fit a 119px cell. */
.opwho .cell .k{margin-top:6px;font-size:9px;letter-spacing:.1em;text-transform:uppercase;font-weight:600;line-height:1.3;color:var(--color-neutral-600)}
.opwho .cell .c{margin-top:4px;font-size:11px;line-height:1.35;color:var(--color-neutral-600);font-variant-numeric:tabular-nums}
/* What the headline figure is made of, set small and flat under it. Three facts on one line, so
   the split that stopped chat drowning the journal is legible rather than merely applied. */
.opsplit{display:flex;flex-wrap:wrap;gap:4px 16px;margin-top:10px;font-size:11px;line-height:1.4;
  color:var(--color-neutral-600);font-variant-numeric:tabular-nums}
.opsplit b{font-weight:700;color:var(--color-text)}
.opsplit.flat{margin:0 -18px;padding:11px 18px;border-top:1px solid var(--color-divider);font-size:12px}
/* The people who have not been in. A name and how long, nothing else. */
.opdrift .gone{margin-top:10px;display:flex;flex-direction:column;gap:1px}
.opdrift .gone .one{display:flex;align-items:baseline;gap:10px;padding:5px 0;
  border-top:1px solid var(--color-divider)}
.opdrift .gone .nm{flex:1;min-width:0;font-size:14px;font-weight:700;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.opdrift .gone .more{padding:7px 0 0;font-size:11px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--color-neutral-600);border-top:1px solid var(--color-divider)}
.opdrift .gone .ago{flex:none;font-size:11px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;
  color:var(--color-neutral-600);font-variant-numeric:tabular-nums}
/* A sub-line under a meter row: what the bar is made of, where the bar alone is only a shape. */
.opsub2{margin-top:3px;font-size:11px;line-height:1.35;color:var(--color-neutral-600);font-variant-numeric:tabular-nums}
/* Everybody, one row each. A name, how long since they were seen, and four counts under it. */
.opall{margin:0 -18px}
.opall .one{padding:11px 18px;border-top:1px solid var(--color-divider)}
.opall .hd{display:flex;align-items:baseline;gap:10px}
.opall .nm{flex:1;min-width:0;font-size:15px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.opall .ago{flex:none;font-size:11px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;
  color:var(--color-neutral-600);font-variant-numeric:tabular-nums}
.opall .ago.bad{color:var(--accent-text)}
.opall .fig{display:flex;flex-wrap:wrap;gap:3px 14px;margin-top:6px;font-size:11px;line-height:1.4;
  color:var(--color-neutral-600);font-variant-numeric:tabular-nums}
.opall .fig b{font-weight:700;color:var(--color-text)}
/* Written a great deal and answered not at all is the row worth seeing from across the screen. */
.opall .fig .bad b, .opall .fig span.bad{color:var(--accent-text)}
.opdrift{margin:0 -18px;padding:13px 18px;border-top:1px solid var(--color-divider);border-left:3px solid var(--color-accent)}
.opdrift.calm{border-left-color:var(--color-divider)}
.opdrift span{font-size:14px;line-height:1.45;font-weight:500}
/* ─── monitoring: status ─────────────────────────────────────────────────── */
/* The four states differ by structure, not only by colour: colour alone is not enough separation
   for a decision this consequential, and one of the four is "I could not load my own data". */
.opstatus{border:0;padding:8px 0 4px}
.opstatus .word{font-family:var(--font-heading);font-weight:800;font-size:38px;line-height:.95;letter-spacing:-.035em;text-transform:uppercase}
.opstatus .well{margin:8px 18px;padding:20px 16px 18px;border-radius:var(--radius-md);background:var(--surface-1)}
.opstatus .well .line{margin-top:12px;font-size:13px;line-height:1.45;color:var(--color-neutral-700)}
.opstatus .check{display:flex;align-items:center;gap:8px;margin-top:14px;padding-top:12px;border-top:1px solid var(--rule)}
.opstatus .check i{flex:none;width:9px;height:9px;border-radius:50%;background:var(--color-text);display:block}
.opstatus .check span{font-size:11px;line-height:1.35;color:var(--color-neutral-600)}
/* Wrong is a card of the accent's tint, its word in the accent's text colour (5.3:1 and 5.7:1 on it). */
.opstatus .bad{margin:8px 18px;border:0;border-radius:var(--radius-md);background:var(--accent-tint);padding:18px 16px 16px}
.opstatus .bad .word{color:var(--accent-text)}
.opstatus .reasons{margin-top:14px;display:flex;flex-direction:column}
.opstatus .reason{display:flex;align-items:flex-start;gap:10px;text-align:left;border:0;border-top:1px solid var(--color-divider);
  background:none;color:var(--color-text);font:inherit;cursor:pointer;padding:11px 0;min-height:44px}
.opstatus .reason .t{flex:1;min-width:0;font-size:14px;line-height:1.4;font-weight:500}
.opstatus .reason .go{flex:none;display:flex;align-items:center;gap:5px;font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  font-weight:800;color:var(--accent-text);padding-top:2px}
.opstatus .bad .check{margin-top:12px;padding-top:10px}
/* Unknown may never be reachable by degrading Well: different word, different border, different
   ground, and everything below it goes quiet. */
.opstatus .hatch{margin:8px 18px;border-radius:var(--radius-md);padding:16px;background-image:repeating-linear-gradient(45deg,transparent 0 7px,var(--color-neutral-300) 7px 8px)}
.opstatus .unknown{border:2px dashed var(--text-2);border-radius:12px;background:var(--color-bg);padding:18px 16px 16px}
.opstatus .unknown .line{margin-top:12px;font-size:14px;line-height:1.45;font-weight:500}
.opstatus .unknown .sub{margin-top:8px;font-size:12px;line-height:1.5;color:var(--color-neutral-700)}
.opstatus .unknown button{margin-top:16px;min-height:44px;width:100%;border:0;border-radius:var(--radius-md);background:var(--sel-bg);
  color:var(--sel-fg);font-family:var(--font-heading);font-weight:800;font-size:12px;letter-spacing:.1em;text-transform:uppercase;
  text-align:left;padding:0 14px;cursor:pointer}
.stale{opacity:.4}
/* What this phone is running, at the very bottom of Me. Quiet by default — it is only interesting
   when it disagrees with the server, and then it says so and offers to fix itself. */
.build{padding:18px 16px 28px;text-align:center;font-size:11px;color:var(--color-neutral-600);font-variant-numeric:tabular-nums}
.build .ver{display:block}
.build button{display:block;margin:8px auto 0;min-height:36px;padding:0 13px;cursor:pointer;
  border:0;border-radius:18px;background:var(--accent-tint);color:var(--accent-tint-text);font:inherit;
  font-family:var(--font-heading);font-weight:800;font-size:10px;letter-spacing:.08em;text-transform:uppercase}
/* The footer. Quieter than the version above it, because it is not information anybody came for. */
.build .rights{display:block;margin-top:6px;font-size:9px;letter-spacing:.06em;color:var(--color-neutral-500)}
.build.stale{color:var(--accent-text);opacity:1}
.build.stale .rights{color:var(--color-neutral-500)}

/* ─── the picture, up close ──────────────────────────────────────────────── */
/* A photo needs a neutral surround to be looked at, so the ground here is ink in both themes — it
   is the one place in the app that does not follow the theme, because a picture judged against a
   white page is a different picture. Nothing else is on it: the caption, the hearts and the frame
   all belong to the post, and this is the picture on its own. See js/zoom.js for the gesture. */
.zoomer{position:absolute;inset:0;z-index:60;display:flex;align-items:center;justify-content:center;
  overflow:hidden;touch-action:none;user-select:none;-webkit-user-select:none}
/* The ground is a layer of its own (drop 6), so it can fade while the picture flies out of the page
   and back into it; zoom.js moves both. It used to be the viewer's background, faded in by CSS. */
.zoomer .zdim{position:absolute;inset:0;background:#161514;will-change:opacity}
.zoomer img{position:relative;flex:none;max-width:100%;max-height:100%;display:block;transform-origin:center center;
  will-change:transform;-webkit-user-drag:none}
/* The way out is the post's own round button: a 38px dark disc drawn inside the 44px it is hit at. */
.zoomer .out{position:absolute;top:calc(env(safe-area-inset-top) + 6px);right:6px;width:44px;height:44px;
  display:grid;place-items:center;border:3px solid transparent;border-radius:50%;background:rgba(28,26,25,.55);background-clip:padding-box;
  color:#f3f2f2;cursor:pointer}
.zoomer .out:hover{background-color:rgba(28,26,25,.75)}

/* ─── the camera ─────────────────────────────────────────────────────────── */
/* Its own dark chrome whatever the app's theme is: a viewfinder is dark, and light chrome over it
   would be unreadable. The tokens are overridden inside this screen rather than referenced around
   it, so every control in here is written the same way as every control anywhere else.

   Accent means recording, here and nowhere else on this screen. */
.jr-cam{--color-bg:#f3f2f2;--color-text:#f3f2f2;--color-divider:rgba(243,242,242,.45);
  --color-neutral-300:rgba(243,242,242,.22);--color-neutral-600:rgba(243,242,242,.65);
  --color-neutral-700:rgba(243,242,242,.8)}
.cam{position:absolute;inset:0;z-index:70;background:#0d0c0c;overflow:hidden;
  color:#f3f2f2;user-select:none;-webkit-user-select:none;touch-action:none}
.camview{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;background:#0d0c0c;
  transform:scale(var(--camcrop,1));transition:transform .06s linear;opacity:0}
/* Shown only once the lens has presented frames of its own. WebKit draws a camera's first frames as
   contain and then snaps them to cover — the viewfinder that opened small and went big. Opacity
   and nothing else, so the box never moves while it waits. */
.camview.on{opacity:1}
/* The freeze-frame: what was on the glass at the shutter, drawn here in the tap itself and left up
   until the picture under it has decoded. Blurred, it is the last frame while the lens turns round. */
.camfreeze{position:absolute;inset:0;width:100%;height:100%;display:block;visibility:hidden;pointer-events:none}
.camfreeze.on{visibility:visible}
.camfreeze.blur{filter:blur(16px) brightness(.8);transform:scale(1.08)}
/* The lens did not come back after the app was away. The whole picture is the button. */
.camresume{position:absolute;inset:0;display:grid;place-items:center;border:0;padding:0;background:rgba(13,12,12,.55);
  color:#fff;font:inherit;cursor:pointer}
.camresume span{display:inline-flex;align-items:center;gap:8px;height:44px;padding:0 18px;border-radius:22px;
  background:rgba(28,26,25,.6);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);font-size:13px;font-weight:800}
/* The lenses, as the phone's camera offers them, as the handoff draws an overlay chip on a photo:
   a pill on dark glass, 13/800, the one in use light. Drawn 30 inside a 44 hit area. */
.camlens{display:flex;gap:4px;justify-content:center}
.camlens button{min-width:44px;height:44px;padding:0 12px;border:0;border-top:7px solid transparent;border-bottom:7px solid transparent;border-radius:15px/22px;
  background:rgba(28,26,25,.6);background-clip:padding-box;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  color:#fff;font:inherit;font-size:13px;font-weight:800;font-variant-numeric:tabular-nums;cursor:pointer}
.camlens button.on{background-color:#f1eeec;color:#1f1d1c}
/* People aim a front camera in a mirror image. The flip is here and only here — every draw takes
   the frame the lens gave, because a mirrored photo of a label cannot be put right afterwards.
   The crop rides along with it: where the browser will not give us the sensor's own zoom, a pinch
   is this scale on the preview and the same centre crop in the draw, so the picture that is framed
   and the picture that is kept are one picture. */
.camview.flip{transform:scaleX(-1) scale(var(--camcrop,1))}
/* The gestures have their own surface over the picture and under the chrome, so every control on
   top of it still belongs to itself. */
.camtap{position:absolute;inset:0;touch-action:none}
/* What the pinch has reached, in the corner, only while it is more than nothing. */
.camzoom{position:absolute;left:50%;transform:translateX(-50%);top:calc(env(safe-area-inset-top) + 62px);
  padding:5px 10px;border-radius:12px;background:rgba(28,26,25,.6);
  font-family:var(--font-heading);font-weight:800;font-size:12px;font-variant-numeric:tabular-nums;
  pointer-events:none}
/* Four lines, not nine boxes. */
.camgrid{position:absolute;inset:0;pointer-events:none}
.camgrid i{position:absolute;background:rgba(243,242,242,.35)}
.camgrid i:nth-child(1){left:33.333%;top:0;bottom:0;width:1px}
.camgrid i:nth-child(2){left:66.666%;top:0;bottom:0;width:1px}
.camgrid i:nth-child(3){top:33.333%;left:0;right:0;height:1px}
.camgrid i:nth-child(4){top:66.666%;left:0;right:0;height:1px}

.camtop{position:absolute;left:0;right:0;top:0;padding:14px;padding-top:calc(14px + env(safe-area-inset-top));
  display:flex;align-items:flex-start;justify-content:space-between;gap:10px}
.camx{width:44px;height:44px;flex:none;display:grid;place-items:center;border:3px solid transparent;border-radius:50%;
  background:rgba(28,26,25,.55);background-clip:padding-box;color:#f3f2f2;cursor:pointer}
.camtools{display:flex;align-items:center;gap:8px}
/* One control, three states — not three buttons. Filled light when it is doing something, so the
   state is visible without reading the word; otherwise the dark glass every control over the
   picture is. A pill and a disc, as the rest of the app's chips and round buttons are. */
/* Both drawn at 36 and hit at 44 (a button is border-box): a clear 4px border with the fill
   clipped inside it, and the same 4px given back as margin, so nothing around them moves. */
.camflash{display:inline-flex;align-items:center;gap:6px;height:44px;padding:0 12px;cursor:pointer;
  border:4px solid transparent;margin:-4px;background-clip:padding-box;
  border-radius:22px;background-color:rgba(28,26,25,.55);color:#f3f2f2;font:inherit;
  font-size:10px;letter-spacing:.1em;text-transform:uppercase;font-weight:800}
.camflash.on{background-color:#f3f2f2;color:#0d0c0c}
.camgridbtn{width:44px;height:44px;flex:none;display:grid;place-items:center;cursor:pointer;
  border:4px solid transparent;margin:-4px;background-clip:padding-box;
  border-radius:50%;background-color:rgba(28,26,25,.55);color:#f3f2f2}
.camgridbtn.on{background-color:#f3f2f2;color:#0d0c0c}
/* Mid-take the flash and the grid mean nothing, so the clock takes their place. */
/* The deeper red, as the light theme's primary: the clock is 14px white, 4.2:1 on #ec3013 and 5.1 on this. */
.camrec{display:inline-flex;align-items:center;gap:8px;height:36px;padding:0 12px;border-radius:18px;background:#d42a10;color:#f3f2f2}
.camrec i{width:10px;height:10px;border-radius:50%;background:#f3f2f2;display:block;flex:none}
.camrec b{font-family:var(--font-heading);font-weight:800;font-size:14px;font-variant-numeric:tabular-nums}

.cambottom{position:absolute;left:0;right:0;bottom:0;padding:0 14px 14px;
  padding-bottom:calc(14px + env(safe-area-inset-bottom));display:flex;flex-direction:column;align-items:center;gap:14px}
/* What has been taken so far, when the camera is collecting for a collage. A strip rather than a
   grid: four at most, and they are in the order they will be laid out in. */
/* What was just taken, filling the screen while you decide. A clip is shown whole. A photo is shown
   as it was framed: in the box the viewfinder covered with the frame (.camfit, sized in camera.js),
   and covered into it, so the swap from the freeze-frame does not move by a pixel. */
.camshot-big{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;display:block;background:#0d0c0c}
.camfit{position:absolute;overflow:hidden}
.camfit .camshot-big{object-fit:cover}
/* Two words, equal weight, the keeping one filled. Wide, because there is nothing else to hit. */
.camkeep{width:100%;display:flex;gap:10px;align-items:center}
/* One height and one line: .cambtn + .cambtn stacks the denied screen's buttons 8px apart, which
   in this row put Use it 8px lower than Retake and stretched Retake to 56. */
.camkeep .cambtn{flex:1;height:48px;min-height:48px}
.camkeep .cambtn + .cambtn{margin-top:0}
.camtray{width:100%;display:flex;gap:6px;justify-content:center}
.camshot{position:relative;width:52px;height:52px;flex:none;display:block;border-radius:12px}
.camshot img{width:100%;height:100%;object-fit:cover;display:block;border-radius:12px}
.camshot .x{position:absolute;right:-5px;top:-5px;width:20px;height:20px;display:grid;place-items:center;
  border:0;border-radius:50%;background:#0d0c0c;box-shadow:0 0 0 2px rgba(243,242,242,.45);color:#f3f2f2;cursor:pointer}
/* The count sits on the tick rather than beside it: the button is 48px and a word does not fit. */
.camsq.done b{position:absolute;right:-5px;top:-5px;min-width:18px;height:18px;padding:0 4px;border-radius:9px;
  display:grid;place-items:center;background:#d42a10;color:#f3f2f2;
  font-family:var(--font-heading);font-weight:800;font-size:11px;font-variant-numeric:tabular-nums}
.camsq.done{position:relative}
.camsq.done.on{background:#f3f2f2;color:#0d0c0c}
.camsq[disabled]{opacity:.4;cursor:default}

.camacts{width:100%;display:grid;grid-template-columns:1fr auto 1fr;align-items:center;justify-items:center}
.camacts .camsq:first-child{justify-self:start}
.camacts .camsq:last-child{justify-self:end}
.camsq{width:48px;height:48px;flex:none;display:grid;place-items:center;cursor:pointer;
  border:0;border-radius:50%;background:rgba(243,242,242,.22);color:#f3f2f2}
/* Round, and 3px of it, since the softer restyle: the app's buttons are round where they are one
   thing to press, and this is the one thing on the screen. Unfilled until it is recording; what it
   stops is a rounded square, the way a phone's own camera draws it. */
.shutter{width:76px;height:76px;flex:none;display:grid;place-items:center;cursor:pointer;
  border:3px solid #f3f2f2;border-radius:50%;background:none;padding:0;-webkit-tap-highlight-color:transparent}
.shutter.rec{background:var(--color-accent);border-color:#f3f2f2}
.shutter.rec i{width:22px;height:22px;border-radius:6px;background:#f3f2f2;display:block}
.shutter.held{position:absolute;left:0;top:50%;margin-top:-38px;z-index:2}
/* Nothing to photograph yet. Dim rather than gone: the shutter keeps its place, so the row does not
   move under the thumb the moment the lens wakes up. */
.shutter.waiting{opacity:.45;cursor:default}
.shutter.stop{background:var(--color-accent)}
.shutter.stop i{width:26px;height:26px;border-radius:6px;background:#f3f2f2;display:block}

/* Held: the row is replaced by the track, because while you are holding it there is nothing else
   on this screen you could be about to do. */
.camlock{position:relative;width:100%;height:76px}
.camlock .track{position:absolute;left:38px;right:24px;top:50%;height:2px;margin-top:-1px;border-radius:1px;background:rgba(243,242,242,.45)}
.camlock .chev{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:flex;gap:8px}
.camlock .chev i{width:7px;height:7px;border-top:2px solid rgba(243,242,242,.65);border-right:2px solid rgba(243,242,242,.65);transform:rotate(45deg);display:block}
.camlock .lockbox{position:absolute;right:0;top:50%;margin-top:-24px;width:48px;height:48px;
  display:grid;place-items:center;border:2px dashed rgba(243,242,242,.65);border-radius:50%;color:#f3f2f2}
.camlock .lockbox.over{border-style:solid;background:rgba(243,242,242,.22)}

.locked{display:flex;align-items:center;gap:8px;justify-self:start}
.locked b{font-family:var(--font-heading);font-weight:700;font-size:10px;letter-spacing:.1em;text-transform:uppercase}
.lockbox.filled{width:36px;height:36px;flex:none;display:grid;place-items:center;border-radius:50%;background:#f3f2f2;color:#0d0c0c}

.camhint{font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:rgba(243,242,242,.72);text-align:center}
.camhint.loud{color:#f3f2f2}

/* No access is not a dead viewfinder. The library still works without the camera, so it is offered. */
.camdeny{position:absolute;inset:0;display:grid;place-items:center;padding:24px}
/* The top bar sits over it, so the way out is never behind the thing explaining why you are here. */
.camdeny + .camtop{z-index:2}
.camdeny .box{border:0;border-radius:var(--radius-md);background:#2c2928;padding:20px;max-width:300px;width:100%}
.camdeny .h{font-family:var(--font-heading);font-weight:800;font-size:22px;line-height:1.05;letter-spacing:-.02em}
.camdeny p{margin:10px 0 18px;font-size:13px;line-height:1.5;color:rgba(243,242,242,.8)}
.cambtn{display:block;width:100%;min-height:44px;cursor:pointer;border:0;border-radius:var(--radius-md);background:rgba(243,242,242,.16);
  color:#f3f2f2;font-family:var(--font-heading);font-weight:800;font-size:11px;letter-spacing:.1em;text-transform:uppercase}
.cambtn + .cambtn{margin-top:8px}
.cambtn.fill{background:#f3f2f2;color:#0d0c0c}

/* ─── games ─────────────────────────────────────────────────────────────── */
/* A game is a full-screen thing, over everything else the way the camera is, and it keeps the
   app's own paper rather than going dark: this is a page of the journal being played, not a
   console. The one rule the layout has to hold is that the canvas gets whatever is left after the
   bar and the hint, measured in CSS pixels — the stage reads clientWidth/clientHeight off it and
   a box that is still growing when that is read is a game drawn at the wrong size. */
.gamescreen{position:absolute;inset:0;z-index:70;background:var(--color-bg);color:var(--color-text);
  display:flex;flex-direction:column;user-select:none;-webkit-user-select:none;touch-action:none}
/* The bar is a sub-screen's: a round close drawn 38 in its 44, the game's name in the small
   capitals, the score at display size. The stage is a card with 14px corners on the surface. */
.gametop{display:flex;align-items:center;gap:10px;padding:8px 18px 10px 7px;padding-top:calc(8px + env(safe-area-inset-top));flex:0 0 auto}
.gamex{width:44px;height:44px;flex:none;display:grid;place-items:center;border:3px solid transparent;border-radius:50%;
  background:var(--surface-1);background-clip:padding-box;color:inherit;cursor:pointer}
.gamename{flex:1;min-width:0;font-family:var(--font-heading);font-weight:800;font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--text-2)}
.gamescore{font-family:var(--font-heading);font-size:26px;font-weight:800;letter-spacing:-.02em;font-variant-numeric:tabular-nums;min-width:2ch;text-align:right}
.gamebox{flex:1 1 auto;position:relative;margin:0 14px;background:var(--surface-1);
  border:0;border-radius:var(--radius-md);overflow:hidden}
.gamecv{display:block;touch-action:none}
/* Somebody you have just gone past, while you are still playing.
   Over the stage and never in the way of it: pinned to the top, a hand's width clear of the number
   in the corner, and gone in a couple of seconds whether or not anything else happens. It is ink on
   paper like the rest of the app — the accent on this screen belongs to the piece you are holding,
   and a second loud thing would be one too many. It slides down, holds, and goes back the way it
   came; the whole of it is one animation and no JavaScript per frame. */
.gpass{position:absolute;left:50%;top:10px;z-index:3;display:flex;flex-direction:column;
  align-items:center;gap:2px;padding:8px 16px;border-radius:var(--radius-md);background:var(--sel-bg);color:var(--sel-fg);
  box-shadow:0 8px 24px rgba(0,0,0,.25);pointer-events:none;white-space:nowrap;
  animation:gpassin 2.2s cubic-bezier(.2,.9,.3,1) forwards}
.gpass .t{font-family:var(--font-heading);font-weight:800;font-size:14px;letter-spacing:-.01em}
.gpass .s{font-size:9px;letter-spacing:.12em;text-transform:uppercase;opacity:.72}
@keyframes gpassin{
  0%{transform:translate(-50%,-140%) scale(.92);opacity:0}
  9%{transform:translate(-50%,0) scale(1.04);opacity:1}
  16%{transform:translate(-50%,0) scale(1)}
  82%{transform:translate(-50%,0) scale(1);opacity:1}
  100%{transform:translate(-50%,-140%) scale(.96);opacity:0}}
@media (prefers-reduced-motion:reduce){
  .gpass{animation:gpasshold 2.2s steps(1) forwards}
  @keyframes gpasshold{0%{transform:translate(-50%,0);opacity:1}96%{opacity:1}100%{opacity:0}}}
.gamecount{position:absolute;inset:0;display:grid;place-items:center;font-family:var(--font-heading);font-size:88px;font-weight:800;
  color:var(--color-text);opacity:.25;pointer-events:none;animation:gamecount .5s ease-out}
@keyframes gamecount{from{transform:scale(1.5);opacity:.05}to{transform:scale(1);opacity:.25}}
.gamehint{flex:0 0 auto;padding:10px 18px 16px;padding-bottom:calc(16px + env(safe-area-inset-bottom));text-align:center;font-size:13px;line-height:1.45;color:var(--muted)}
.gameover{position:absolute;inset:0;display:grid;place-items:center;background:color-mix(in srgb,var(--color-bg) 82%,transparent);padding:16px}
.gameover .box{width:100%;max-width:320px;background:var(--bar);border:0;border-radius:var(--radius-lg);
  padding:20px 16px 16px;display:flex;flex-direction:column;gap:8px;box-shadow:0 8px 30px rgba(0,0,0,.3)}
.gameover .big{font-family:var(--font-heading);font-size:30px;font-weight:800;letter-spacing:-.03em;text-align:center;line-height:1.1}
.gameover .sub{text-align:center;font-size:13px;color:var(--muted);margin-bottom:4px}
.gameover .btn{border-radius:var(--radius-md);font-weight:800}
/* Picking one. Four cards, each its name and the one line that says how it goes — anything longer
   is a manual, and nobody reads a manual to play for ninety seconds. */
.gamepick{flex:1;overflow:auto;padding:4px 14px 20px;display:flex;flex-direction:column;gap:8px}
.gamecard{display:flex;flex-direction:column;gap:4px;text-align:left;padding:14px 16px;cursor:pointer;
  background:var(--surface-1);border:0;border-radius:var(--radius-md);color:inherit;font:inherit}
.gamecard .n{font-family:var(--font-heading);font-size:17px;font-weight:800;letter-spacing:-.01em}
.gamecard .h{font-size:13px;line-height:1.4;color:var(--muted)}
.gamenote{padding:18px;display:flex;flex-direction:column;gap:12px}
.gamenote p{margin:0;font-size:15px}

/* The board, on the post. Ranked, and your own row marked — on a leaderboard the only two things
   anybody looks for are who won and where they came. */
.board{background:var(--jr-photo);color:var(--jr-photo-ink);border:2px solid var(--jr-photo-ink);
  padding:14px;display:flex;flex-direction:column;gap:10px}
.boardhead{display:flex;align-items:center;gap:9px}
.boardhead .gt-mark{width:26px;height:26px}
.boardname{font-family:inherit;font-size:12px;letter-spacing:.12em;text-transform:uppercase}
.boardlist{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px}
.boardrow{display:flex;align-items:center;gap:8px;padding:5px 6px;font-size:14px}
/* The leader's row, tinted from the board's own ink rather than from a theme colour.
   --jr-desk is the desk *behind* the app and it flips to near-black in the dark theme — but this
   board sits on paper-white in both themes, like every photo frame and chip in here, so a row
   painted with it came out black under ink that is also dark, and the winner's name was the one
   line on the board nobody could read. Mixed from --jr-photo-ink, it is the same light grey
   whichever theme is on. */
.boardrow.top{background:color-mix(in srgb,var(--jr-photo-ink) 11%,transparent)}
.boardrow.me{font-weight:700}
.boardrow .pos{width:16px;font-variant-numeric:tabular-nums;color:var(--jr-photo-mute)}
/* First place, drawn rather than numbered. A "1" beside a "2" is a fact you read; the accent block
   is the one thing on the board that catches the eye on the way past, which is what holding the
   record is for. The number is still there for a screen reader, on the label. */
.boardrow.top .pos{display:flex;align-items:center}
.boardrow .best{display:block;width:11px;height:11px;background:var(--color-accent)}
.boardrow.top .num{font-weight:800}
.boardrow .who{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.boardrow .goes{font-size:11px;color:var(--jr-photo-mute)}
.boardrow .num{font-variant-numeric:tabular-nums}
.hero-game{padding:4px 14px 0}
/* On the post since the softer restyle: a card on the surface, rows with corners, the leader's on
   the accent's tint and still marked by a round accent dot. */
.hero-game .board{border:0;border-radius:var(--radius-md);background:var(--surface-1);color:var(--text);padding:16px}
.hero-game .boardname{font-weight:800;color:var(--text-2)}
.hero-game .boardrow{border-radius:10px}
.hero-game .boardrow.top{background:var(--accent-tint)}
.hero-game .boardrow .pos,.hero-game .boardrow .goes{color:var(--muted)}
.hero-game .boardrow .best{border-radius:50%}

/* On the spread: the score, big, and who holds it. */
.t-game{display:flex;flex-direction:column;gap:6px}
.gametile{background:var(--jr-photo);color:var(--jr-photo-ink);border:2px solid var(--jr-photo-ink);
  padding:12px 14px;display:flex;align-items:center;gap:12px}
.gt-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
/* The game's own mark, over on the right. Four white cards in a row down a spread all looked the
   same until this was on them — the words say which game, but not before you have read them. */
.gt-mark{flex:none;width:58px;height:58px;display:block}
.gt-mark rect{fill:var(--jr-photo-ink)}
.gt-mark rect.hot{fill:var(--color-accent)}
.gt-head{display:flex;align-items:baseline;gap:8px}
.gt-kick{font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--jr-photo-mute)}
.gt-name{font-size:12px;font-weight:700}
.gt-score{font-size:26px;font-weight:700;line-height:1.1;font-variant-numeric:tabular-nums}
.gt-who{font-size:13px}
.gt-foot{font-size:11px;color:var(--jr-photo-mute)}

/* In the composer: the card in the grid, and the chip in the tray. */
/* Pac-Man on the Game card: accent for him, ink for the dots he is going after. `crispEdges` on the
   element rather than a filter, so the pixels stay pixels at every screen density. */

/* ─── making a video smaller ─────────────────────────────────────────────── */
/* Over everything, because it is the only thing happening: the clip is being played through a
   canvas in real time and nothing else on the screen would do anything useful if it were tapped.
   The one accent is the bar, which is the thing being waited on. */
/* Its own names throughout. Every one of the six this started with — box, ttl, say, bar, pct,
   skip — was already taken somewhere in this stylesheet, and .bar in particular is the top bar of
   half the screens in the app: its 12px of padding landed inside the progress track and the bar
   read 39% where it had been told 42. That is the third time this file has taught the same lesson,
   so this block spells its own names out. */
.shrink{position:absolute;inset:0;z-index:74;display:grid;place-items:center;padding:20px;
  background:color-mix(in srgb,var(--color-neutral-900) 72%,transparent)}
.shrink .shbox{width:100%;max-width:330px;padding:20px 18px 16px;background:var(--bar);
  border:0;border-radius:var(--radius-lg);box-shadow:0 8px 30px rgba(0,0,0,.3)}
.shrink .shttl{font-family:var(--font-heading);font-weight:800;font-size:20px;letter-spacing:-.02em}
.shrink .shsay{margin-top:8px;font-size:13px;line-height:1.5;color:var(--text-2)}
/* The design's bar: a rounded track on the step above, filled in the accent. */
.shrink .shbar{margin-top:14px;height:8px;border-radius:4px;overflow:hidden;background:var(--surface-2)}
.shrink .shbar i{display:block;height:100%;border-radius:4px;background:var(--color-accent);transition:width .25s linear}
.shrink .shpct{margin-top:6px;font-size:10px;letter-spacing:.1em;font-weight:600;
  color:var(--muted);font-variant-numeric:tabular-nums}
/* Not a cancel: the video still goes up, it is just the big one. So it says what it does. A filled
   row, as every quiet second action in the app now is. */
.shrink .shskip{display:flex;align-items:center;gap:8px;width:100%;min-height:48px;margin-top:14px;
  padding:0 14px;border:0;border-radius:var(--radius-md);background:var(--surface-1);color:var(--text);
  cursor:pointer;text-align:left;font:inherit;font-family:var(--font-heading);font-weight:800;
  font-size:11px;letter-spacing:.1em;text-transform:uppercase}

/* ─── your picture ──────────────────────────────────────────────────────── */
/* The same shape as the camera's review: the thing being decided about fills the screen, and the
   decisions sit under it where a thumb already is. Dark whatever the theme, because a face is
   easier to judge against something that is not competing with it. */
/* Your picture, in the app's own theme.
   It was drawn on a hardcoded near-black, which made it the one screen here that ignored the
   theme — and a face judged against black is not the face everybody else sees against the app's
   own ground. Every colour below is a token. */
.picscreen{position:absolute;inset:0;z-index:72;background:var(--color-bg);color:var(--color-text);
  display:flex;flex-direction:column;overflow:hidden}
.picscreen .pictop{display:flex;align-items:center;gap:10px;padding:10px 18px 10px 7px;padding-top:calc(10px + env(safe-area-inset-top));flex:0 0 auto;
  border:0}
/* 44px to hit, a bare glyph as every sub-screen's way back is, its press drawn round. */
.picscreen .picx{width:44px;height:44px;margin-left:0;display:grid;place-items:center;background:none;border:0;border-radius:50%;
  color:inherit;cursor:pointer;padding:0}
.picscreen .pictitle{flex:1;min-width:0;margin:0;font-family:var(--font-heading);font-weight:800;font-size:22px;
  letter-spacing:-.02em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.picscreen .picbody{flex:1;min-height:0;overflow:auto;padding-bottom:calc(24px + env(safe-area-inset-bottom))}
/* Full width and square. No padding round it and no corners: it is the subject, not an illustration
   of one, and it is the one thing here that is not a control. */
.picscreen .picbig{display:block;width:100%;aspect-ratio:1;padding:0;border:0;cursor:pointer;
  background:var(--surface-1)}
.picscreen .picav{width:100%;height:100%;font-size:120px;border-radius:0}
.picscreen .pichint{padding:12px 18px 4px;font-size:12px;line-height:1.5;color:var(--muted);border:0}
/* Three cells, one control: a photograph, an initial and a symbol are three answers to one
   question. Filled tiles with 14px corners, the one you are on the light chip. */
.picscreen .picmode{display:flex;gap:8px;padding:10px 18px 4px;border:0}
.picscreen .mcell{flex:1;min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:6px;
  min-height:64px;padding:11px 12px;cursor:pointer;border:0;border-radius:var(--radius-md);
  background:var(--surface-1);color:var(--text);font:inherit;text-align:left}
.picscreen .mcell .lbl{font-family:var(--font-heading);font-weight:800;font-size:10px;
  letter-spacing:.1em;text-transform:uppercase}
.picscreen .mcell.on{background:var(--sel-bg);color:var(--sel-fg)}
.picscreen .mcell:disabled{opacity:.55}
.picscreen .picklbl{padding:16px 18px 8px;font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  font-weight:600;color:var(--muted)}
/* Eight at once rather than a row you scroll: you are choosing between them, and a choice you
   cannot see the whole of is not one. Filled cells a little apart, as the emoji grids are. */
.picscreen .avgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;padding:0 18px;background:none;border:0}
.picscreen .avpick{height:74px;display:grid;place-items:center;padding:0;cursor:pointer;border:0;border-radius:var(--radius-md);
  background:var(--surface-1);color:var(--text-2)}
.picscreen .avpick.on{background:var(--sel-bg);color:var(--sel-fg)}
.picscreen .avpick:disabled{opacity:.55}
.picscreen .avpick svg{display:block;color:inherit;background:none}
/* ─── the journals list ─────────────────────────────────────────────────── */
/* Find a journal. Only on screen once there are enough of them that scrolling is slower than
   typing — the same rule the old Last-used strip used, and for the same reason. */
/* A filled field like every other one, and the ring is the field's, not the input's inside it.
   The input is the whole of the field, edge to edge and top to bottom, with the glass and the clear
   button laid over it: a field drawn 44px tall that only focuses in a 36px strip right of the glass
   is a field that ignores a thumb on its own edge. The right padding is always kept, since the
   clear button is there whenever there is any text to run under it. */
.jfind{position:relative;display:flex;align-items:center;gap:10px;min-height:44px;margin:6px 18px 0;padding:0;border-radius:var(--radius-md);
  background:var(--surface-1);color:var(--muted)}
.jfind:focus-within{outline:2px solid var(--color-accent);outline-offset:2px}
.jfind>svg{position:absolute;left:14px;top:50%;margin-top:-7.5px;pointer-events:none}
.jfind input{flex:1;align-self:stretch;min-width:0;background:none;border:0;outline:0;font:inherit;font-size:15px;color:var(--color-text);padding:0 46px 0 39px}
.jfind input::placeholder{color:var(--placeholder);opacity:1}
.jfind input::-webkit-search-cancel-button{display:none}
.jclear{background:none;border:0;padding:4px;color:inherit;cursor:pointer;display:grid;place-items:center}
.jfind .jclear{position:absolute;right:14px;top:50%;margin-top:-11px}
/* The kinds, as chips. What used to be four headings with four walls under them: the list stays one
   list and these narrow it, which is the difference between a filter and a filing cabinet. */
.kindchips{display:flex;gap:6px;padding:10px 18px 4px;overflow-x:auto}
/* Drawn at the design's 30, hit at the 34 they have been since stage 1: a 2px clear edge above and
   below, the fill clipped inside it. */
.kchip{flex:none;min-height:34px;padding:0 13px;font:inherit;font-size:13px;font-weight:800;line-height:1;cursor:pointer;
  background-color:var(--surface-1);background-clip:padding-box;color:var(--text-2);
  border:solid transparent;border-width:2px 0;border-radius:14px/16px}
.kchip.on{background-color:var(--sel-bg);color:var(--sel-fg)}

/* A journal once it is not the thing you came for: the same cover at 46px, the name on a line of
   its own so it is read rather than recognised, and the count on the right when there is one.
   Twelve of these fit on a screen where four posters did. */
/* The way in to the one big feed, under the chips and over the journals. Quiet on purpose: it is
   one more way to look at what is already on this screen, not a journal, so it gets the divider
   and the inset a row gets and none of the weight a cover gets. */
.feedway{display:flex;align-items:center;gap:10px;width:calc(100% - 36px);margin:0 18px;
  min-height:44px;padding:0;border:0;border-bottom:1px solid var(--rule);
  background:none;font:inherit;color:var(--color-text);cursor:pointer;text-align:left}
.feedway .w{flex:1;min-width:0;font-size:13px;font-weight:800}
.feedway svg{flex:none}
.jrows{display:flex;flex-direction:column;padding:0 14px 6px}
.jrow{display:flex;align-items:center;gap:11px;padding:9px 2px;cursor:pointer;
  border-bottom:1px solid var(--color-divider);text-align:left;min-width:0}
.jrow:last-child{border-bottom:0}
/* Home's list is ruled from the top, as the design draws it: a rule between the covers and the
   first row, none under the last. Scoped, because the picker's journal list is a .jrow too. */
.home .jrows{padding:0 18px 6px}
.home .jrow{gap:12px;padding:9px 0;border-bottom:0;border-top:1px solid var(--rule)}
.home .jrows.invites .jrow:first-child{border-top:0}
.rcover{flex:none;width:46px;height:46px;overflow:hidden;background:var(--surface-1);display:block;border-radius:12px}
.rcover .media-box,.rcover img{width:100%;height:100%;object-fit:cover;display:block}
.rbody{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.rname{font-family:var(--font-heading);font-size:15px;font-weight:800;line-height:1.2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:flex;align-items:center;gap:5px}
.rlast{font-size:13px;line-height:1.3;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* The count, in the accent, on the right. It is the one thing on a row that is allowed to shout. */
.rnew{flex:none;min-width:22px;height:22px;padding:0 7px;display:grid;place-items:center;border-radius:11px;
  background:var(--accent-fill);color:#fff;font-size:12px;font-weight:800;font-variant-numeric:tabular-nums}

/* A cover on Home is a 6:5 picture over its name since the softer restyle, which draws it that way.
   It was 3:4 here, because these covers are made as book covers and a landscape crop of a portrait
   painting cuts off part of what somebody chose; the crop is the picture's middle (cover). The
   journal settings and Create still show the whole 3:4 cover. */

/* An invitation is a row like any other, with its one word on the right. */
.jrows.invites{padding-bottom:0}
.jrow.invite .rcover{background:var(--color-accent-100,var(--color-neutral-100))}
.jrow.invite .rcover img{width:100%;height:100%;object-fit:cover;display:block}
/* The row is the target; its word is drawn as a small tinted pill, the one soft accent on it. */
.rlook{flex:none;display:grid;place-items:center;min-height:28px;padding:0 12px;border-radius:14px;
  background:var(--accent-tint);color:var(--accent-tint-text);font-family:var(--font-heading);
  font-size:11px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}


/* ─── round 10: the comments, in a popup over whatever you were looking at ───
   One height. The sheet it replaces had two and a drag between them, which put a question to you —
   the thoughts, or the post? — that you had already answered by tapping what you tapped. */

/* The wash is the dismiss target as well as the dimming, which is why it is a real element and not
   a shadow on the popup: tapping past the popup is the gesture everybody tries first. */
/* Absolute inside the shell, not fixed to the window. `#desk` is the element that follows the
   visual viewport — it is what `--vvh` is for — and `.shell` fills it, so an absolute child of the
   shell loses height to the keyboard exactly as every other screen does. Fixed positioning measures
   the layout viewport instead, which does not move when a keyboard opens: the popup stayed its full
   height, the field stayed at the bottom of it, and the keyboard covered the thing you had just
   tapped to type into. */
.cwash{position:absolute;inset:0;z-index:40;background:rgba(0,0,0,.58);border:0;padding:0;
  display:block;-webkit-tap-highlight-color:transparent}
.cpop{position:absolute;left:0;right:0;bottom:0;top:38%;z-index:40;box-sizing:border-box;
  display:flex;flex-direction:column;min-height:0;overflow:hidden;
  background:var(--bar);border-radius:24px 24px 0 0;
  box-shadow:var(--sheet-shadow)}
/* Rounded at the top. This used to say "no rounding, here as everywhere", with a hard 2px rule
   across the top and a heavy shadow doing the lifting instead.
   9.7.4 overturns that on purpose: Ali put this beside Instagram's comment sheet in one recording
   and said Instagram's "looks just better" — 12px corners, a grabber, no line across the top, and a
   surface a step lighter than the dimmed page in the dark theme, so it stands off it without a rule.
   The softer restyle takes the corners to 24px and the surface to the bars' colour in both themes.
   The bottom sheets (.sheet-backdrop>.sheet) wear the same. */
/* The grabber: a centred bar that says this can be pulled down. Drawn over the top of whatever the
   sheet starts with, takes no touch, and is not `.grab` — that name is the What's-new drawing's. */
.grabber{position:absolute;top:8px;left:50%;z-index:1;width:40px;height:5px;margin-left:-20px;border-radius:3px;
  background:var(--grab);pointer-events:none}
/* The popup's grabber has a strip of its own, because its header is full from edge to edge — the
   four actions sit where a centred bar would. A handle like the header: no scrolling from it. */
.cpop .cgrip{flex:none;height:14px;touch-action:none}
/* 9.7.3: the popup is the wash's sibling, not its child — the wash fades and the popup must not
   fade with it — so it carries the wash's z-index itself and is drawn after it. On its way out
   both are a picture: no pointer, and inert, so a tap lands on whatever is behind. */
.cwash.leaving,.cpop.leaving{pointer-events:none}
/* The screen under the popup steps back, the way a screen does under a sheet on a phone: smaller,
   from the top, its top corners rounded and dark all round it, in either theme. The black is the
   shell's, so the screen is given its own paper for as long as it is shown on it — the same colour
   it was getting from the shell, so nothing about it changes but what is around it. The movement
   itself is in cpop.js (Web Animations, on transform only), and none of this applies while the
   popup is closed. */
.shell.receding{background:#000}
.shell.receding>.screen,.shell.receding>.jkeep:not(.under){background:var(--color-bg);transform-origin:50% 0}
.shell.receding>.tabbar{transform-origin:50% 0}
/* Its two top corners. A radius cannot move on the compositor, so the rounding is black drawn over
   each corner and moved with it — on black, that is a clip. Two pixels larger than the 12px curve
   outward, so the edge of the screen can never show past it, and scaled down to nothing at rest. */
.ccorner{position:absolute;top:-2px;z-index:39;width:14px;height:14px;pointer-events:none;transform:scale(.001)}
.ccorner.l{left:-2px;transform-origin:2px 2px;background:radial-gradient(circle at 100% 100%,transparent 11.5px,#000 12px)}
.ccorner.r{right:-2px;transform-origin:12px 2px;background:radial-gradient(circle at 0 100%,transparent 11.5px,#000 12px)}

/* Who and when, on one line. The two-line block this replaces spent a whole line on the journal's
   name, which is already at the top of the screen behind the popup. */
/* The chrome is the drag handle: a touch that lands on it may only put the popup away, never
   scroll something behind it. The thoughts keep `pan-y` — they are a scroller first and a handle
   only when they are already at the top. */
.cpop .chead,.cpop .ccap{touch-action:none}
/* The design's head: the face, the name, the time, the four actions in their pill and a bare
   close; a soft rule under it. The name gives way before the time does. */
.cpop .chead{flex:none;display:flex;align-items:center;gap:9px;padding:6px 8px 10px 18px;
  border-bottom:1px solid var(--rule)}
.cpop .chead .who{flex:0 1 auto;min-width:0;font-family:var(--font-heading);font-weight:800;font-size:15px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cpop .chead .at{flex:1 0 auto;font-style:normal;font-size:12px;color:var(--muted);
  font-variant-numeric:tabular-nums}
/* The four actions, as one control rather than four loose glyphs.
 *
 * Their styling went out with the sheet's block in round 10 and nothing replaced it, so they had
 * been rendering as bare unstyled buttons — which is how they came to be reported as not looking
 * like the app. Four bare icons floating in a bar is the one shape this app uses nowhere else.
 * Since the softer restyle the one control is a pill on the surface with four round cells in it:
 * the one you liked fills with the accent, its opposite with the light segment, because a journal
 * is not a place to keep score. */
.acts-min{display:flex;flex:none;gap:2px;padding:3px;border:0;border-radius:20px;background:var(--surface-1)}
.acts-min button{width:34px;height:30px;display:grid;place-items:center;padding:0;border:0;border-radius:15px;
  background:none;color:var(--color-text);cursor:pointer;
  -webkit-tap-highlight-color:transparent}
.acts-min button.on{background:var(--accent-fill);color:var(--on-accent)}
.acts-min button.nope.on{color:var(--sel-fg);background:var(--sel-bg)}
.cpop .chead .acts-min{margin-left:auto}
/* Bare, as the design draws it. 44 tall to hit, with the 4px over the pill's height taken back out
   of the head by the margins, so the head keeps the design's height. */
.cpop .cx{flex:none;width:36px;height:44px;margin:-4px 0;display:grid;place-items:center;padding:0;border:0;border-radius:50%;
  background:none;color:var(--text);cursor:pointer}
/* A narrow phone: the time goes under the name, as on the post's own author line, so the name has
   the whole of what is left beside the face instead of the time keeping its width and the name
   giving way first. Two lines of 15 and 12 are no taller than the pill beside them. */
@media (max-width:359px){
  .cpop .chead{display:grid;grid-template-columns:26px minmax(0,1fr) auto auto;grid-template-rows:auto auto;
    row-gap:0}
  .cpop .chead>.avatar{grid-column:1;grid-row:1/3}
  .cpop .chead .who{grid-column:2;grid-row:1;align-self:end;line-height:18px}
  .cpop .chead .at{grid-column:2;grid-row:2;align-self:start;line-height:15px;min-width:0;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .cpop .chead .acts-min{grid-column:3;grid-row:1/3}
  .cpop .chead .cx{grid-column:4;grid-row:1/3}
}

/* The caption and the count on one line: the count in small capitals at the right, the way the
   design puts it at the top of the thoughts. Apart they were two blocks and about forty-six pixels. */
.cpop .ccap{flex:none;display:flex;align-items:baseline;gap:10px;padding:10px 18px 2px;border:0}
.cpop .ccap .t{flex:1;min-width:0;font-size:13px;line-height:1.35;color:var(--text-2);
  overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.cpop .ccap .n{flex:none;margin-left:auto;font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;
  color:var(--muted);white-space:nowrap}

.cpop .clist{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;touch-action:pan-y;
  -webkit-overflow-scrolling:touch;scrollbar-width:none;padding:0 18px}
.cpop .clist::-webkit-scrollbar{display:none}
.cpop .replies{padding:0}
.cpop .replies.empty{padding:14px 0;display:flex;flex-direction:column;gap:5px}
.cpop .replies.empty b{font-family:var(--font-heading);font-weight:800;font-size:17px}
.cpop .replies.empty span{font-size:13px;color:var(--muted)}

/* ── a thought ─────────────────────────────────────────────────────────────
   The design's row, the same as on the post: a 26px face, the name and the time on one line, the
   words under them, and the thought's own reaction pinned to the top at the far end — a pill with
   the face and the count, or a round heart — with a soft rule under each. About 57px for a line of
   words, where round 10's inline run was 33. */
.cpop .reply{display:grid;grid-template-columns:26px minmax(0,1fr) auto;gap:0 10px;align-items:start;
  padding:10px 0;border:0;border-bottom:1px solid var(--rule)}
.cpop .reply .avatar{grid-column:1;align-self:start}
.cpop .reply .c{grid-column:2;min-width:0;display:flex;flex-wrap:wrap;align-items:baseline;column-gap:6px;row-gap:2px;
  font-size:13px;line-height:normal;overflow-wrap:anywhere}
.cpop .reply .rn{min-width:0;margin:0;font-family:var(--font-heading);font-weight:800;font-size:13px}
.cpop .reply .rt{margin:0;font-style:normal;font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums}
.cpop .reply .x{display:block;flex:0 0 100%;min-width:0;font-size:14px;line-height:1.4}
.cpop .reply .rx{grid-column:3;align-self:start;height:26px;min-width:26px;padding:0;
  box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;gap:4px;
  border:0;border-radius:13px;background:var(--surface-1);color:var(--muted);
  cursor:pointer;font-size:12px;line-height:1}
.cpop .reply .rx.has{padding:0 9px;color:var(--text)}
.cpop .reply .rx.mine{background:var(--accent-tint);color:var(--text)}
.cpop .reply .rx b{font-family:var(--font-heading);font-size:12px;font-weight:800;font-variant-numeric:tabular-nums}
.cpop .reply .rx .e{font-size:13px;line-height:1}
/* The picker spans the text column and the chip's, so it starts on the same left edge the words do. */
.cpop .reply .rxstrip{grid-column:2/4;margin-top:8px}
.cpop .reply .rxstrip .rxcell{height:38px}

/* The answer field is first in the list and inside it, because it is content and not chrome —
   somebody who has answered already can scroll it away. A card of its own, filled, like the
   post's. */
.cpop .answerbox{margin:10px 0 4px;padding:14px;border:0;border-radius:var(--radius-md);background:var(--surface-1)}
.cpop .answerbox .ak{margin:0 0 8px;font-size:10px;font-weight:800;letter-spacing:.1em;
  text-transform:uppercase;color:var(--accent-text)}
.cpop .answerbox .input{width:100%;box-sizing:border-box;border-radius:var(--radius-md);background-color:var(--surface-2);
  padding:12px;resize:none}
/* Not full width: it is one button in a box, not the box's footer. */
.cpop .answerbox .abtn{height:40px;margin-top:10px;padding:0 18px}
.cpop .answerbox .note{margin-top:8px;font-size:11px;line-height:1.45;color:var(--muted)}

/* Six faces across the width: the one-tap answer to a picture, and the reason an empty thread is
   not a dead end. It reacts to the post, never to a comment. Seven equal buttons, filled and
   rounded, a little apart — the design's quick bar — and yours on the accent's tint. */
.qrow{flex:none;display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:4px;padding:8px 12px 0;border:0}
.qrow .qcell{height:40px;display:grid;place-items:center;padding:0;border:0;border-radius:var(--radius-md);
  background:var(--surface-1);font-size:19px;line-height:1;cursor:pointer;color:var(--text);
  -webkit-tap-highlight-color:transparent}
.qrow .qcell.on{background:var(--accent-tint)}
.qrow .qcell.more{font-size:0}

/* ─── the comment button: a card's second target ────────────────────────────
   An explicit zero invites nobody, so a post nobody has said anything about shows the outline on
   its own — see CommentButton, which draws no number at all in that case. */
/* `box-sizing` and `line-height` spelled out so the height is 28 and not whatever the label's line
   box comes to — a control that grows when its count reaches double figures is a control that
   moves the row it sits in. (It also measures taller than 28 from outside, and that one is not the
   button's doing: a card is tilted, and the bounding box of a rotated element is the box around
   the rotation. Measure it with offsetHeight.) */
.cbtn{position:relative;box-sizing:border-box;flex:none;height:28px;min-width:28px;padding:0 6px;
  margin-left:auto;line-height:1;
  display:inline-flex;align-items:center;justify-content:center;gap:4px;
  border:1px solid var(--jr-photo-ink);background:none;color:var(--jr-photo-ink);cursor:pointer}
.cbtn.big{height:30px}
.cbtn b{font-size:10px;font-weight:700;font-variant-numeric:tabular-nums}
/* A square, like every other mark in this app, and outlined in the paper colour so it reads against
   a photograph as clearly as against paper. */
.cbtn .nm{position:absolute;top:-4px;right:-4px;width:9px;height:9px;
  background:var(--color-accent);border:2px solid var(--jr-photo)}

/* ─── the whole post, in one scroll ─────────────────────────────────────────
 * The cap on the picture is the whole trick. A photograph given the room it asks for pushes
 * everything anybody said about it below the fold, and below the fold is the same as behind a tap.
 * Half the screen: the picture whole, resized rather than cropped, and the conversation in the
 * other half. `--vvh` and not `vh`, because the shell is what the keyboard shortens and `vh` would
 * go on measuring a screen that is no longer there. `contain` so nothing is cut off — the point is
 * to see all of it, and tapping it opens the viewer where it can be pinched. */
/* A square window the picture fills, rather than a fixed height it is letterboxed inside.
   250px with `contain` was right that the window must be a known size and wrong about the shape:
   a box that is not the picture's shape leaves the difference as margin, and on an upright phone
   photo that margin was most of the paper. A square has no side to be wrong about — it takes the
   same bite out of an upright picture as a sideways one, where 4:5 is kind to one and brutal to
   the other — and measured at 430x932 it still leaves the count line and four thoughts above the
   fold, where 4:5 leaves one.
   `--focus` is which square: two percentages chosen while composing, the middle for a photograph
   posted before that existed. Nothing is cut to make it. The card on the spread still draws the
   picture's own shape and a tap still opens all of it. */
.detail.onescroll .posthero .hero-shot,.detail.onescroll .posthero .media-box{
  aspect-ratio:1;height:auto;max-height:none}
.detail.onescroll .posthero .hero-shot img,.detail.onescroll .posthero .media-box img{
  width:100%;height:100%;object-fit:cover;object-position:var(--focus,50% 50%)}
/* A photograph keeps the shape it really is, and is cut only by the screen.
   The square above was the right answer to the wrong question. Measured at full width, a square
   picture stands 386px on a 430x932 phone and leaves 314 spare under it; on a 320x568 it stands
   276 and leaves 60. Three hundred pixels going begging on one phone and none on the other means
   no single shape can serve both — 4:5 is generous on the big one and takes the caption off the
   small one — which is why #113 chose the square and why the shape was never the thing to choose.
   Height is, and it belongs against the screen. So: the picture's own shape, full width, and a
   ceiling of 62 vertical percent. An ordinary upright camera photograph clears that on a big phone
   and is shown whole; so is every landscape one, which used to lose its sides. Only a picture
   taller than the screen can take is cut, and then in its height, from the framing point — never
   narrowed, and never given a margin. svh where a browser has it, because a tab's chrome is part
   of what the screen cannot take; vh is the same number once the app is on the Home Screen. */
.detail.onescroll .posthero .hero-shot.own{aspect-ratio:auto}
/* `width:100%` is load-bearing, not tidying. A box whose width is only `auto` has no definite
   width, so when max-height bites the browser works the width back out of the aspect ratio and the
   picture comes out narrow with paper down both sides — the very margin this is here to avoid.
   Measured before the width was pinned: a 9:16 picture on a 430 wide phone drew 325px across
   instead of 386. A definite width cannot be recomputed, so the height clamps alone and `cover`
   takes the difference out of the picture, which is the crop we want. */
/* Since the softer restyle the width is the screen's, not the paper's, so the same shape stands
   taller. Two ceilings, by what a picture is: 58% of the screen for anything taller than a camera
   takes (the ceiling the suites hold the post to), and 64% for a camera's own upright 3:4 or wider
   (.camshape, post.js), so an ordinary camera photograph is still shown whole on a phone, as #132
   asked — at the screen's width it needs 62% of an iPhone's height, where the margins kept it
   under 56. The thread still starts higher than it did, because the bar and the author's line now
   lie over the picture instead of above it. The second ceiling is only for a screen at least twice
   as tall as it is wide — a phone, standing, with the app on its Home Screen — and not for a short
   one (a browser's own bars, a small phone), where it would push the count line under the fold. */
.detail.onescroll .posthero .hero-shot.own .media-box{width:100%;max-height:58vh}
@supports (height:1svh){.detail.onescroll .posthero .hero-shot.own .media-box{max-height:58svh}}
@media (max-aspect-ratio:1/2){
  .detail.onescroll .posthero .hero-shot.own.camshape .media-box{max-height:64vh}
  @supports (height:1svh){.detail.onescroll .posthero .hero-shot.own.camshape .media-box{max-height:64svh}}
}
/* A video is drawn as a photograph is (drop 6, Ali: "could you make this homogen"): its own shape
   (inline, post.js), the full width, the author's line over its foot. With one difference: it is
   never cut. A photograph's crop is a view of a picture a tap opens whole; a video has no viewer,
   so a cut is a part of it nobody can ever see — a 9:16 lost 44% of its height. So it gets a higher
   ceiling, and anything that still does not fit is drawn whole inside its box on the dark ground. */
.detail.onescroll .posthero .media-box.vidbox{width:100%;max-height:80vh;background:#161514;cursor:pointer;
  -webkit-tap-highlight-color:transparent}
@supports (height:1svh){.detail.onescroll .posthero .media-box.vidbox{max-height:80svh}}
.detail.onescroll .posthero .media-box.vidbox video{width:100%;height:100%;object-fit:contain}
/* Its three controls, Instagram's: a glyph that comes and goes in the middle on a tap, a speaker
   drawn 28 inside the 44 it is hit at, above the author's line, and a line along the foot that
   fills as it plays. Over the author's line's shade (z-index 2), which takes no touches itself. */
.vidbox .vglyph{position:absolute;left:50%;top:50%;z-index:3;width:64px;height:64px;margin:-32px 0 0 -32px;
  display:grid;place-items:center;border-radius:50%;background:rgba(28,26,25,.55);pointer-events:none;
  animation:jrGlyph .6s ease-out forwards}
@keyframes jrGlyph{0%{opacity:0;transform:scale(.8)}20%{opacity:1;transform:scale(1)}70%{opacity:1}100%{opacity:0;transform:scale(1)}}
.vidbox .vglyph.held{animation:jrGlyphIn .2s ease-out forwards}
@keyframes jrGlyphIn{from{opacity:0;transform:scale(.8)}to{opacity:1;transform:scale(1)}}
@media (prefers-reduced-motion:reduce){.vidbox .vglyph{animation:none;opacity:0}.vidbox .vglyph.held{opacity:1}}
.vidbox .vmute{position:absolute;right:6px;bottom:6px;z-index:3;width:44px;height:44px;padding:0;
  display:grid;place-items:center;border:8px solid transparent;border-radius:50%;
  background:rgba(28,26,25,.55);background-clip:padding-box;color:#fff;cursor:pointer;
  -webkit-tap-highlight-color:transparent}
.screen.detail.onpic:not(.shortpic) .vidbox .vmute{bottom:50px}
.vidbox .vline{position:absolute;left:0;right:0;bottom:0;z-index:3;height:2px;background:rgba(255,255,255,.28);pointer-events:none}
.vidbox .vline i{position:absolute;inset:0;background:#fff;transform:scaleX(0);transform-origin:0 50%}
/* And a picture the app composed is the other two, for the same reason the video is: a collage and
   a doodle have a shape somebody chose while making them and no framing step to choose a square
   with. A 3:2 collage in a square window lost a third of its width — reported with two screenshots
   of the same post, whole on the spread and cut in half here, with a person missing out of one of
   its three photographs. So the box takes the picture's shape instead of the picture taking the
   box's. `contain` because the stored ratio is rounded to four places and cover would shave the
   last hair off an edge; at a matching shape it shows no bands. The width is capped rather than
   the height (see the inline max-width): clamping a full-width box's height keeps its width and
   letterboxes, which is the grey band this screen exists to be rid of. */
.detail.onescroll .posthero .hero-shot.whole{aspect-ratio:auto}
.detail.onescroll .posthero .hero-shot.whole .media-box{margin-inline:auto}
.detail.onescroll .posthero .hero-shot.whole img{object-fit:contain;object-position:center}
/* The row under the picture: the tally from the left, then Like and Nope sharing what is left —
   the design's three pills, 38 tall. Like is the light pill with a filled heart once it is yours,
   and the plain surface with an outline heart until then (the design draws only the first). Nope
   is the plain surface, and the light pill when it is yours. Many faces on one post wrap the tally
   and put the two buttons on a line of their own rather than squeeze them. */
/* `border:0` and `min-height:0`: the map's list rows are also .brow, and their rule under each row
   and their 56px were reaching this one. */
.detail .body .brow{display:flex;flex-wrap:wrap;align-items:center;gap:6px;padding:0;min-height:0;border:0;cursor:auto}
.detail .body .brow svg{color:inherit}
.detail .body .brow .rxrow{flex:0 1 auto;min-width:0;margin:0}
.detail .body .brow .rxrow:empty{display:none}
.detail .body .pacts{flex:1 0 180px;display:flex;gap:6px;margin:0}
.detail .pact{flex:1 1 0;min-width:0;height:38px;padding:0 12px;display:inline-flex;align-items:center;justify-content:center;gap:6px;
  border:0;border-radius:19px;background:var(--surface-1);color:var(--text);cursor:pointer;
  font-family:var(--font-heading);font-weight:800;font-size:11px;letter-spacing:.08em;
  text-transform:uppercase;line-height:1;-webkit-tap-highlight-color:transparent}
.detail .pact span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.detail .pact svg{flex:none}
.detail .pact.on{background:var(--sel-bg);color:var(--sel-fg)}
/* At 320 German's GEFÄLLT MIR needs 85px and the pill gives the word 67. Below 340, in the languages
   whose words are longer than the drawing's, the pills give up their glyphs and some padding: the
   word, and the light fill when it is yours, still say which. */
@media (max-width:340px){
  :root:not(:lang(en)) .detail .pact{padding:0 8px}
  :root:not(:lang(en)) .detail .pact svg{display:none}
}
/* Who, on a thin line of its own under the strip, and only when somebody has: a tally cannot say
   whose it is, and a chip with a 2 on it is a question until this answers it. */
.detail .body .saidby{margin:8px 0 0;padding:0 4px;font-size:12px;line-height:1.35;color:var(--muted)}
/* Since drop 7 it is a button, and a tap on it says who: the sheet of everybody (WhoSheet). Drawn
   where it was and hit at 44. The 8px over the words is its own top padding now rather than a
   margin, so they do not move and the box meets the row of chips without covering it; the 20px
   under them reaches 14px into the thoughts' head, whose top padding has nothing to tap in it, so
   the head comes down 6px rather than 20. Positioned, so it is the one hit there and not the head. */
.detail .body button.saidby{position:relative;display:block;width:100%;box-sizing:border-box;margin:0 0 -14px;
  padding:8px 4px 20px;border:0;background:none;font:inherit;font-size:12px;line-height:1.35;text-align:left;
  color:var(--muted);cursor:pointer;-webkit-tap-highlight-color:transparent}

/* The square the post will show, drawn over the whole picture rather than instead of it. What is
   outside it is still in the journal — on the card, and under a tap — so hiding it would be a lie
   about what posting does. Shades, not a crop. */
/* Long names on purpose. `.k` and `.d` are kickers and details all over this sheet — `.editor .k`
   alone carries a 26px top margin — and the compose screen is an `.editor`, so a short name here
   is not a name, it is a collision waiting for someone to measure it. */
.photoframe .sqguide{position:absolute;inset:0;pointer-events:none}
.photoframe .sqguide .sqdim{position:absolute;margin:0;padding:0;background:rgba(0,0,0,.52)}
.photoframe .sqguide .sqkeep{position:absolute;margin:0;padding:0;
  box-shadow:0 0 0 1px rgba(255,255,255,.9) inset}
.photoframe .sqguide .sqkeep::before,.photoframe .sqguide .sqkeep::after{content:'';position:absolute;
  left:0;right:0;height:1px;background:rgba(255,255,255,.34)}
.photoframe .sqguide .sqkeep::before{top:33.33%}
.photoframe .sqguide .sqkeep::after{top:66.66%}

/* Who wrote it: the face, the name with the time under it, and Keep and Curate at the far end, as
   round buttons. Over the foot of a photograph (see "a photograph, under its own bar"), under a
   video, and above anything else. The bar at the top of the screen carries the journal and the
   day; it used to carry this as well, which was saying it twice. */
.detail .pby{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;grid-template-rows:auto auto;
  column-gap:9px;row-gap:1px;align-items:center;padding:12px 18px 4px}
.detail .pby .avatar{grid-column:1;grid-row:1/3;width:30px;height:30px;font-size:13px}
.detail .pby b{grid-column:2;grid-row:1;align-self:end;min-width:0;font-family:var(--font-heading);font-weight:800;
  font-size:15px;line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.detail .pby .at{grid-column:2;grid-row:2;align-self:start;font-size:12px;line-height:1.25;color:var(--muted);
  font-variant-numeric:tabular-nums}
.detail .pby .pico{grid-column:3;grid-row:1/3;width:34px;height:34px;display:grid;place-items:center;padding:0;
  border:0;border-radius:50%;background:var(--surface-1);color:var(--text);cursor:pointer;
  -webkit-tap-highlight-color:transparent}
.detail .pby .pico:last-child{grid-column:4}

/* The picture, the caption and the strip are still one piece, but nothing is mounted round them
   any more: a photograph is the whole width of the screen, and what is said about it sits on the
   page under it. A note never had paper and has none of the grain either. */
.detail .paper{background:none}
.detail .paper.mounted{margin:0;padding:0;background:none;box-shadow:none}
.detail .paper.mounted .body{padding:12px 14px 0;color:var(--text)}
.heroslot{position:relative}
/* How many, and which end they start from: the count in capitals and the order as a pill. */
.detail .thead{display:flex;align-items:center;gap:10px;padding:14px 18px 2px}
.detail .thead .kicker{flex:1;min-width:0;margin:0;font-family:var(--font-heading);font-size:11px;font-weight:800;
  letter-spacing:.1em;color:var(--text)}
.detail .thead .rule{display:none}
.detail .thead .ord{flex:none;display:inline-flex;align-items:center;gap:4px;height:30px;padding:0 12px;border:0;border-radius:15px;
  background:var(--surface-1);color:var(--text-2);cursor:pointer;
  font-family:var(--font-heading);font-size:10px;font-weight:800;letter-spacing:.1em;
  text-transform:uppercase;-webkit-tap-highlight-color:transparent}
/* A thought, as the design draws it: the face, the name and the time on one line and the words
   under them, the thought's own reaction at the far end, and a soft rule under each. About 57px for
   a line of words. The popup's rules are written against `.cpop`, so the post needs its own copy
   of them rather than a shared selector, which is the price of the two frames being separate
   elements. */
.detail.onescroll .replies{padding:0 18px}
.detail.onescroll .replies.empty{padding:14px 18px 18px;display:flex;flex-direction:column;gap:5px}
.detail.onescroll .replies.empty b{font-family:var(--font-heading);font-weight:800;font-size:17px}
.detail.onescroll .replies.empty span{font-size:13px;color:var(--muted)}
.detail.onescroll .reply{display:grid;grid-template-columns:26px minmax(0,1fr) auto;gap:0 10px;align-items:start;
  padding:10px 0;border:0;border-bottom:1px solid var(--rule)}
.detail.onescroll .reply .avatar{grid-column:1;align-self:start}
.detail.onescroll .reply .c{grid-column:2;min-width:0;display:flex;flex-wrap:wrap;align-items:baseline;column-gap:6px;row-gap:2px;
  font-size:13px;line-height:normal;overflow-wrap:anywhere}
.detail.onescroll .reply .rn{min-width:0;margin:0;font-family:var(--font-heading);font-weight:800;font-size:13px}
.detail.onescroll .reply .rt{margin:0;font-style:normal;font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums}
.detail.onescroll .reply .x{display:block;flex:0 0 100%;min-width:0;font-size:14px;line-height:1.4}
.detail.onescroll .reply .rx{grid-column:3;align-self:start;height:26px;min-width:26px;padding:0;
  box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;gap:4px;
  border:0;border-radius:13px;background:var(--surface-1);color:var(--muted);
  cursor:pointer;font-size:12px;line-height:1}
.detail.onescroll .reply .rx.has{padding:0 9px;color:var(--text)}
.detail.onescroll .reply .rx.mine{background:var(--accent-tint);color:var(--text)}
.detail.onescroll .reply .rx b{font-family:var(--font-heading);font-size:12px;font-weight:800;font-variant-numeric:tabular-nums}
.detail.onescroll .reply .rx .e{font-size:13px;line-height:1}
.detail.onescroll .reply .rxstrip{grid-column:2/4;margin-top:8px}
.detail.onescroll .reply .rxstrip .rxcell{height:38px}
/* The faces and the field are pinned, so answering never depends on having scrolled to the end of
   what everybody else said. On the page, with nothing ruled above them. */
.detail.onescroll .qrow{border-top:0}

/* ─── a picture, under its own bar ─────────────────────────────────────────
   The picture runs to the edges and to the top, and the bar is laid over it: the back and the
   more as round buttons of frosted dark glass, the journal and the day in white on a shade that
   falls off down the picture. Its author is laid over its foot the same way. Neither takes a touch
   except on its buttons, and a tap that lands on either opens nothing (onTheMedia, post.js).
   Blur is kept to these few buttons: there is one picture on this screen, where a spread has a
   chip on every tile and a layer for each.
   Once the picture has gone up past it the bar is the plain bar every other post has (.offpic,
   set by detail.js), and takes touches again. 10.5.0 sat it above the picture on the page;
   10.5.1 lays it back over (Ali: "revert the post layout to how it was with the transparent"),
   over a video too, whose controls are now in its middle and at its foot. */
.screen.detail>.bar{gap:8px;padding:11px 11px 7px;border-bottom:0;background:var(--bar)}
.screen.detail.onpic{position:relative}
.screen.detail.onpic>.bar{position:absolute;left:0;right:0;top:0;z-index:3;background:none;color:#fff;pointer-events:none}
/* The design's .6 shade, held the depth of the bar's words before it falls away: falling from the
   very top, it was down to about .35 behind the date, and on a white sky the day read at 3.6:1. */
.screen.detail.onpic>.bar::before{content:'';position:absolute;left:0;right:0;top:0;height:calc(100% + 40px);z-index:-1;
  background:linear-gradient(rgba(0,0,0,.6),rgba(0,0,0,.6) 55%,transparent);pointer-events:none}
.screen.detail.onpic>.bar>.btn.icon-btn{position:relative;pointer-events:auto;background:none;color:#fff}
.screen.detail.onpic>.bar>.btn.icon-btn::before{content:'';position:absolute;inset:3px;border-radius:50%;
  background:rgba(28,26,25,.55);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}
.screen.detail.onpic>.bar>.btn.icon-btn svg{position:relative}
.screen.detail.onpic>.bar .who b{color:#fff}
.screen.detail.onpic>.bar .who span,.screen.detail.onpic>.bar .who .wx{color:#ece8e6}
.screen.detail.onpic>.bar.offpic{background:var(--bar);color:var(--text);pointer-events:auto}
.screen.detail.onpic>.bar.offpic::before{display:none}
.screen.detail.onpic>.bar.offpic>.btn.icon-btn{color:var(--text)}
.screen.detail.onpic>.bar.offpic>.btn.icon-btn::before{background:var(--surface-1);-webkit-backdrop-filter:none;backdrop-filter:none}
.screen.detail.onpic>.bar.offpic>.btn.icon-btn:last-child::before{display:none}
.screen.detail.onpic>.bar.offpic .who b{color:var(--text)}
.screen.detail.onpic>.bar.offpic .who span{color:var(--muted)}
.screen.detail.onpic>.bar.offpic .who .wx{color:var(--text-2)}
/* Its foot's shade is .6 by the top of the name and .72 at the bottom (as the tiles' is): rising from
   nothing across the whole line, it was under .5 behind the name. Not on a wide picture
   (.shortpic, detail.js), whose author's line is under it and drawn as it is under a video. */
.screen.detail.onpic:not(.shortpic) .heroslot>.pby{position:absolute;left:0;right:0;bottom:0;z-index:2;padding:40px 14px 14px;
  background:linear-gradient(transparent,rgba(0,0,0,.6) 40px,rgba(0,0,0,.72));color:#fff;pointer-events:none}
.screen.detail.onpic:not(.shortpic) .heroslot>.pby .avatar{margin:2px;box-shadow:0 0 0 2px #fff}
.screen.detail.onpic:not(.shortpic) .heroslot>.pby .at{color:#ece8e6}
.screen.detail.onpic:not(.shortpic) .heroslot>.pby .pico{pointer-events:auto;background:rgba(28,26,25,.55);color:#fff;
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}
/* Nothing spans the width any more. The block that did was a hundred and thirty pixels of four
   full-width pieces carrying almost no content; its four actions are split by what they are about
   and sit on the two lines that were already there. */
.detail .thead.none .kicker{color:var(--color-text)}

/* ─── Add: four doors over the journal ─────────────────────────────────────
 *
 * A sheet and not a screen. You are usually adding about the thing you are looking at, so the
 * journal stays behind it at a third of its strength — which is what makes opening Add cost
 * nothing, and closing it cost nothing, which is the half people actually feel.
 */
/* Everything outside the sheet closes it, which is the other half of "costs nothing to open".
   It fills the screen's own room rather than the window's, so the tab bar stays below it and stays
   live — Add is raised over what you were reading, not over the app. */
/* ─── Add, round 2 ──────────────────────────────────────────────────────────
   The sheet decides the type at two levels in the same object, every compose screen is fixed
   bands with NEXT in its header, and where it goes is a step of its own. Nothing here scrolls:
   if a kind does not fit, something comes out of it rather than a scrollbar going in. */

/* NEXT, top right, and POST in the same place on the last step: the screen's one primary, filled
   red once there is something to move on with (Softer UI). Not ready is a filled surface with quiet
   ink at FULL opacity — the system's 45% on a filled button collapses the label to 1.7:1 on the dark
   ground and you get a block with an invisible word in it. The pill is drawn 40 tall inside the 46
   it has always been to hit: a 3px clear edge and the fill clipped to the padding box, so the drawn
   corner is the design's 14. */
.compose .cgo{flex:none;height:46px;min-height:46px;padding:0 18px;border:3px solid transparent;border-radius:17px;
  background-color:var(--surface-1);background-clip:padding-box;color:var(--disabled);cursor:pointer;
  font-family:var(--font-heading);font-weight:800;font-size:15px;line-height:1;letter-spacing:0}
.compose .cgo.on{background-color:var(--accent-fill);color:var(--on-accent);border-color:transparent}
.compose .cgo[disabled]{cursor:default}

/* ── Moment · photo and video: six bands, and the picture is the one that stretches ── */
.photoview{display:flex;flex-direction:column;flex:1;min-height:0;gap:12px;padding:14px}
/* The photograph sits in a well of its own, rounded, the dark of a photo in both themes (the
   tiles' ground on the spread), and is contained in it rather than cropped to it. */
.photoview .shot{flex:1;min-height:0;display:flex;align-items:center;justify-content:center;
  background:#151413;border-radius:14px;overflow:hidden;padding:0}
.photoview .shot > *{max-width:100%;max-height:100%}
.photoview .shot img,.photoview .shot video{max-width:100%;max-height:100%;object-fit:contain;display:block}
.photoview .shot .framebox{position:relative;max-height:100%;margin:0 auto}
/* How long the clip is, on the clip. The rule that drew this only ever named `.polaroid .play`,
   and the shot is not in a polaroid here. */
.photoview .shot .play{position:absolute;left:8px;bottom:8px;display:flex;align-items:center;gap:6px;
  background:rgba(28,26,25,.72);color:#fff;border-radius:12px;font-family:var(--font-heading);font-weight:800;
  font-size:11px;letter-spacing:.04em;height:24px;padding:0 8px;pointer-events:none;font-variant-numeric:tabular-nums}
.photoview .shot .media-box{position:relative}
/* Nothing taken yet: the well itself is the way into the camera. */
.photoview .shot .blank{flex:1;align-self:stretch;border:0;background:none;
  color:#a39e9b;cursor:pointer;font:inherit;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:8px;padding:12px}
.photoview .shot .blank span{font-family:var(--font-heading);font-weight:800;font-size:10px;
  letter-spacing:.1em;text-transform:uppercase}
.photoview.frosted .shot img{filter:blur(28px) saturate(1.4);transform:scale(1.18)}
.photoview.frosted .sqguide,.photoview.frosted .framez{display:none}

/* The strip: one thumb per photograph in the post, the `+` that adds another, and a line saying
   what happens if you do. A clip has none of it — there is only ever one. */
.photoview .shotstrip{flex:none;display:flex;align-items:center;gap:8px;min-height:52px}
/* `touch-action:none` is what makes the drag possible at all: without it the browser claims the
   gesture for a scroll the moment the finger moves sideways, and the pointermove events stop
   arriving halfway through. `position:relative` is for the numeral. */
.photoview .shotstrip .thumb{width:52px;height:52px;flex:none;border:0;padding:0;background:var(--surface-1);border-radius:12px;
  cursor:pointer;opacity:.5;position:relative;touch-action:none;-webkit-user-select:none;user-select:none}
/* The one that is the post's — or the big one of several — ringed two pixels out, in the ink. */
.photoview .shotstrip .thumb.on{opacity:1;outline:2px solid var(--text);outline-offset:2px}
.photoview .shotstrip .thumb img{width:100%;height:100%;object-fit:cover;display:block;pointer-events:none;border-radius:12px}
/* Which place in the picture this one takes. The first is the big one, which is why it is the one
   the strip marks, and the numerals say what the marking means. */
.photoview .shotstrip .thumb .n{position:absolute;left:3px;top:3px;min-width:16px;height:16px;padding:0 4px;border-radius:8px;
  background:rgba(28,26,25,.72);color:#fff;font-family:var(--font-heading);font-weight:800;
  font-size:9px;line-height:16px;text-align:center;pointer-events:none}
/* Taking one out. Top right, opposite the numeral, and small — it is on top of the photograph and
   the photograph is the thing being looked at. 22px of target on a 58px thumb, which is under the
   44px a control on its own would get: this one sits inside a much larger one that is easy to hit,
   and making it bigger would be taking the thumb's own area away from the drag. */
.photoview .shotstrip .thumb .x{position:absolute;right:0;top:0;width:22px;height:22px;border:0;padding:0;border-radius:50%;
  background:rgba(28,26,25,.72);color:#fff;cursor:pointer;display:grid;place-items:center;
  touch-action:none}
/* Under the finger: lifted off the strip and fully lit, so the place it will land in is the one
   thing on the strip you can see clearly. */
.photoview .shotstrip .thumb.lift{opacity:1;z-index:2;transform:scale(1.06)}
@media (prefers-reduced-motion:reduce){.photoview .shotstrip .thumb.lift{transform:none;outline:2px solid var(--color-accent);outline-offset:2px}}
/* Two doors, side by side: the shutter and the library. Same box, because neither is the main one
   — which you want depends on whether the photograph exists yet, and that is not a preference. */
.photoview .shotstrip .more,
.photoview .shotstrip .pick{width:52px;height:52px;flex:none;border:0;border-radius:14px;background:var(--surface-1);color:var(--color-text);
  cursor:pointer;display:grid;place-items:center}
/* Two lines at most, then it gives way: with three photographs and two doors beside them there is
   about 70px left for it, and letting it wrap freely turned it into a five-line tower down the
   right-hand edge that was taller than the thumbs. */
.photoview .shotstrip .say{flex:1;min-width:0;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;
  padding:0 0 0 4px;font-family:var(--font-heading);font-weight:800;font-size:10px;line-height:1.4;letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted);overflow:hidden;overflow-wrap:anywhere}
.photoview .shotstrip.lone{padding:0 4px;gap:8px;min-height:44px;color:var(--muted)}
/* Under 340 the line beside the thumbs is narrower than any language's sentence in two lines; a third
   still fits inside the 52px strip. */
@media (max-width:340px){.photoview .shotstrip .say{-webkit-line-clamp:3}}
.photoview .shotstrip.lone .say{padding:0;flex:1}

/* The words under it: a filled field, one line tall, that scrolls inside itself past that. */
.photoview .cap{flex:none;width:100%;height:48px;border:0;border-radius:14px;background:var(--surface-1);resize:none;
  outline:none;font:inherit;font-size:16px;line-height:22px;color:var(--color-text);padding:13px 14px;min-height:0}
.photoview .cap::placeholder{color:var(--placeholder);opacity:1}
.photoview .cap:focus-visible{outline:2px solid var(--color-accent);outline-offset:2px}

/* The tools: four tiles a row, the glyph over the word. Cover is one of them rather than a band
   with a switch in it, filled in the selected chip's colours while it is on. */
.photoview .tools{flex:none;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px}
.photoview .tool{height:64px;padding:0 4px;border:0;border-radius:14px;background:var(--surface-1);
  color:var(--color-text);cursor:pointer;font-family:var(--font-heading);font-weight:800;font-size:12px;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;white-space:nowrap;min-width:0}
/* Cover it is `button.tool.cover`, and `.cover` is also Home's journal cover card, unscoped — its
   aspect ratio and shadow were landing on this tile. Everything that rule could bring is set here. */
.photoview .tool{aspect-ratio:auto;box-shadow:none;margin:0;width:auto;max-width:none;position:relative;overflow:hidden;text-align:center}
.photoview .tool svg{flex:none}
.photoview .tool.wide{grid-column:1 / -1;height:48px;flex-direction:row;gap:8px;font-size:13px}
.photoview .tool.on{background:var(--sel-bg);color:var(--sel-fg)}
/* A tile is 67px wide at 320: Ausschnitt and Verdecken need 70 at 12px and fit at 11. */
@media (max-width:340px){.photoview .tool:not(.wide){font-size:11px}}
.coverask-sheet{position:fixed;inset:0;z-index:70;background:rgba(0,0,0,.4);display:flex;align-items:flex-end}
/* A sheet like every other: the bars' colour, 24px top corners and the sheet shadow, the label in
   the small capitals. */
.coverask-sheet .body{width:100%;background:var(--bar);padding:21px 18px calc(16px + env(safe-area-inset-bottom));
  border:0;border-radius:24px 24px 0 0;box-shadow:var(--sheet-shadow);display:flex;flex-direction:column;gap:10px}
.coverask-sheet .k{font-family:var(--font-heading);font-weight:600;font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted)}
.coverask-sheet p{margin:0;font-size:14px;line-height:1.45;color:var(--text-2)}
.coverask-sheet .note{font-size:12px;line-height:1.45;color:var(--muted);margin:0}

/* ── Question and poll: what you type is the post ── */
.askview{display:flex;flex-direction:column;flex:1;min-height:0;padding:16px 18px 0}
/* The question in a filled field at the weight it lands at. 17px is above the 16px floor every
   field is held to (iOS zooms the page below it), so the floor's !important is answered here. */
.askview .ask{border:0;border-radius:14px;background:var(--surface-1);resize:none;outline:none;font:inherit;
  font-family:var(--font-heading);font-weight:800;font-size:17px !important;line-height:1.15;letter-spacing:-.01em;
  color:var(--color-text);padding:16px 14px;width:100%}
.askview .ask::placeholder{color:var(--placeholder);opacity:1}
.askview .ask:focus-visible{outline:2px solid var(--color-accent);outline-offset:2px}
.askview .slot{margin:8px 0 0;padding-top:12px;display:flex;align-items:center;gap:10px}
.askview .slot i{width:22px;height:22px;flex:none;border-radius:7px;background:var(--rule-head);display:block}
.askview .slot span{font-family:var(--font-heading);font-weight:800;font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--text-2)}
.askview .note{margin:8px 0 0;font-size:12px;line-height:1.5;color:var(--muted)}
.askview .seeds{margin-top:auto;padding:16px 0 calc(16px + env(safe-area-inset-bottom));display:flex;flex-direction:column;gap:8px}
.askview .seeds .k{font-family:var(--font-heading);font-weight:600;font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted);padding-bottom:2px}
.askview .seeds button{min-height:44px;width:100%;border:0;border-radius:14px;background:var(--surface-1);
  color:var(--color-text);cursor:pointer;font:inherit;font-size:15px;text-align:left;padding:0 14px}
.askview .seeds button:active{background:var(--surface-2)}
/* The choices as numbered lines under one rule, which is how they land. */
.askview .choices{margin:16px 0 0;border-top:1px solid var(--rule)}
/* `border:0` first: `.crow` is also a chooser row on another screen and it carries a full 1px box.
   Inheriting it here puts every choice back in the boxes this round took them out of. */
.askview .crow{display:flex;align-items:center;gap:10px;min-height:48px;padding:0 2px;
  border:0;border-bottom:1px solid var(--rule);background:none;
  font:inherit;font-size:inherit;font-weight:inherit;cursor:auto;justify-content:flex-start}
.askview .crow .n{flex:none;font-family:var(--font-heading);font-weight:800;font-size:12px;
  color:var(--color-neutral-700);font-variant-numeric:tabular-nums}
.askview .crow input{flex:1;min-width:0;border:0;background:none;outline:none;font:inherit;
  font-family:var(--font-heading);font-weight:800;font-size:18px;letter-spacing:-.02em;color:var(--color-text)}
.askview .crow input::placeholder{color:var(--color-neutral-700);font-weight:800}
.askview .crow.next input::placeholder{color:var(--color-neutral-700)}
.askview .crow .px{width:30px;height:30px;flex:none;border:0;background:none;color:var(--color-neutral-700);
  cursor:pointer;display:grid;place-items:center}

/* ── Feeling · Scales: every scale is a row with its own track ── */
.feelview{display:flex;flex-direction:column;flex:1;min-height:0;padding:0 18px}
.feelview .fhead{flex:none;display:flex;align-items:baseline;gap:10px;padding:10px 0 2px;
  font-family:var(--font-heading);font-weight:600;font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted)}
.feelview .fhead span{flex:1;min-width:0}
.feelview .fhead b{flex:none;margin-left:auto;font-weight:800;color:var(--muted);font-variant-numeric:tabular-nums}
.feelview .fhead b.some{color:var(--text)}
.feelview .scales{flex:1;min-height:0;display:flex;flex-direction:column}
/* A row: the name and its figure on one line, the bar under it, a rule. 71px, which is ROW_H in
   compose.js — the two have to agree or the rows pile. The cells are the 38px they have always
   been to hit; the bar is 14px painted across their middle, so it sits 12px under the name. What
   the list has left over after the last whole row is shared out between the rows (up to 85px
   each), so the line to write in follows the list rather than a gap. */
.feelview .srow{flex:1 0 auto;max-height:85px;display:flex;flex-direction:column;justify-content:center;
  padding:10px 0 2px;border-bottom:1px solid var(--rule)}
.feelview .srow .hd{height:20px;display:flex;align-items:baseline;gap:8px;cursor:pointer}
.feelview .srow .hd .nm{flex:1;min-width:0;font-family:var(--font-heading);font-weight:800;font-size:15px;line-height:20px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.feelview .srow .hd b{flex:none;font-family:var(--font-heading);font-weight:800;font-size:20px;line-height:20px;
  font-variant-numeric:tabular-nums;color:var(--empty)}
.feelview .srow.on .hd b{color:var(--color-text)}
/* Eleven cells, nought to ten, drawn as one segmented bar: everything up to the figure filled. The
   digit stays in each cell for whoever reads it aloud and for nobody's eye. */
.feelview .srow .cells{display:flex;gap:3px}
.feelview .srow .cells button{flex:1;min-width:0;height:38px;padding:0;border:0;position:relative;
  background:none;color:transparent;cursor:pointer;font:inherit;font-size:0;-webkit-tap-highlight-color:transparent}
.feelview .srow .cells button::before{content:'';position:absolute;left:0;right:0;top:12px;height:14px;
  border-radius:3px;background:var(--surface-2)}
.feelview .srow .cells button:first-child::before{border-radius:7px 3px 3px 7px}
.feelview .srow .cells button:last-child::before{border-radius:3px 7px 7px 3px}
.feelview .srow .cells button.fill::before{background:var(--accent)}
.feelview .newrow{flex:none;min-height:51px;display:flex;align-items:center;gap:10px;padding:12px 0;
  border:0;border-bottom:1px solid var(--rule);background:none;color:var(--text-2);
  cursor:pointer;font:inherit;text-align:left}
.feelview .newrow .pl{width:26px;height:26px;flex:none;border-radius:50%;background:var(--surface-1);display:grid;place-items:center}
.feelview .newrow span{font-family:var(--font-heading);font-weight:800;font-size:14px}
.feelview .cap{flex:none;width:100%;height:44px;margin-top:12px;border:0;border-radius:14px;background:var(--surface-1);
  resize:none;outline:none;font:inherit;font-size:16px;line-height:22px;color:var(--color-text);padding:11px 14px}
.feelview .cap::placeholder{color:var(--placeholder);opacity:1}
.feelview .cap:focus-visible{outline:2px solid var(--color-accent);outline-offset:2px}
.feelview .rule{flex:none;margin:0;padding:8px 0;font-size:11px;line-height:1.45;color:var(--muted)}
.feelview .newscale{display:flex;gap:8px;padding:0 0 12px}
.feelview .newscale .input{flex:1;min-height:44px}

/* ── Where does it go? ── */
.goview{display:flex;flex-direction:column}
.goview .bar .h1{flex:1;min-width:0;font-size:22px;letter-spacing:-.03em;margin:0}
/* Scoped, every one of them: Home lists journals as `.jrow` too, and that list is not this one. */
/* A ruled list in the 18px gutter, as every list is: the row the whole width to hit, the rule drawn
   inside the gutter, the journal's own thumbnail with corners, and a filled box to tick. */
.goview .jrows{border:0;padding:0}
.goview .jrow{display:flex;align-items:center;gap:12px;width:100%;min-height:60px;padding:0 18px;
  border:0;background:linear-gradient(var(--rule),var(--rule)) center bottom / calc(100% - 36px) 1px no-repeat;color:var(--color-text);
  cursor:pointer;font:inherit;text-align:left}
.goview .jrow:active{background-color:var(--surface-1)}
.goview .jrow .jc{width:34px;height:34px;flex:none;display:block;border-radius:10px;background:var(--surface-1);overflow:hidden}
.goview .jrow .jc img{width:100%;height:100%;object-fit:cover;display:block}
.goview .jrow .jc.none{display:grid;place-items:center;font-family:var(--font-heading);font-weight:800;font-size:15px;
  color:var(--color-neutral-700)}
.goview .jrow .nm{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.goview .jrow .nm b{font-family:var(--font-heading);font-weight:800;font-size:18px;letter-spacing:-.02em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.goview .jrow .nm i{font-style:normal;font-size:12px;color:var(--muted)}
/* The box is filled, with 7px corners. Unticked it still needs an edge to be seen at all — the
   surface alone is 1.2:1 on the page — so it keeps a 1.5px ring of the muted ink inside it (5.9:1
   light, 6.3:1 dark); ticked it is the light chip's ink with the tick in the page's colour. */
.goview .jrow .tick{width:26px;height:26px;flex:none;border:0;border-radius:7px;background:var(--surface-1);box-shadow:inset 0 0 0 1.5px var(--muted);
  display:grid;place-items:center;color:var(--sel-fg)}
.goview .jrow.on .tick{background:var(--sel-bg);box-shadow:none}
.goview .hint{padding:13px 18px;font-size:12px;line-height:1.45;color:var(--muted);margin:0}
.gofoot{flex:none;display:flex;align-items:center;gap:8px;padding:12px 18px calc(12px + env(safe-area-inset-bottom));
  border-top:1px solid var(--rule);color:var(--text-2);font-size:13px}
.gofoot b{color:var(--color-text);font-weight:700}

.addback{flex:1;min-height:0;display:flex;flex-direction:column;justify-content:flex-end;position:relative;z-index:30}
/* Raised over what you were doing: the bars' colour, 24px top corners, and the header rule across
   its top edge — no grabber and no shadow, because this one is not dragged. The tile subtitle's
   colour is the sheet's own (#bdb8b5 on dark, the design's; a darker step on light for 4.5:1). */
.addsheet{position:relative;background:var(--bar);border-radius:24px 24px 0 0;
  border-top:2px solid var(--rule-head);padding:18px 14px 14px;--tile-sub:#56514e}
.jr-dark .addsheet{--tile-sub:#bdb8b5}
/* The header is the 36px of its close button. Both buttons keep the 44px they are hit at and give
   the difference back in margin, so the drawn shapes sit where the design puts them. */
.addsheet .ahead{display:flex;align-items:center;gap:10px;padding:0 4px;margin-bottom:12px;height:36px}
.addsheet .ahead .h1{flex:1;min-width:0;font-size:24px;letter-spacing:-.02em;line-height:1;margin:0}
.addsheet .ahead .back{width:44px;height:44px;flex:none;border:0;background:none;color:var(--color-text);
  display:grid;place-items:center;cursor:pointer;margin:-4px -11px -4px -13px}
.addsheet .ahead .x{width:44px;height:44px;flex:none;margin:-4px -4px -4px 0;padding:0;border:4px solid transparent;
  border-radius:16px;background:var(--surface-1);background-clip:padding-box;color:var(--color-text);
  display:grid;place-items:center;cursor:pointer}
/* Four, by what you mean rather than by what the app stores: tiles on the sheet, two a row. */
.addsheet .doors{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.addsheet .door{min-height:96px;padding:14px;border:0;border-radius:14px;background:var(--surface-1);color:var(--color-text);
  cursor:pointer;font:inherit;display:flex;flex-direction:column;align-items:flex-start;gap:4px;text-align:left}
.addsheet .door svg{flex:none;margin-bottom:6px}
.addsheet .door.wide{grid-column:1 / -1;min-height:76px}
.addsheet .door:active{background:var(--surface-2)}
.addsheet .door .nm{font-family:var(--font-heading);font-weight:800;font-size:17px;line-height:1.1;margin-top:auto}
.addsheet .door .un{font-family:var(--font-heading);font-weight:800;font-size:9px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--tile-sub)}
/* What you posted last, in one tap. The thing somebody is about to make is usually the thing they
   just made, and a shortcut to it is the cheapest cut to the deciding there is. */

/* ─── one shell, thirteen views ────────────────────────────────────────────
 *
 * header, body, kinds, foot. Every compose screen is these four bands, so learning one teaches
 * the rest — and the kind can be changed from the title or from the chips without either being
 * in the way of the field.
 */
.cshell{display:flex;flex-direction:column;min-height:0;flex:1;background:var(--color-bg)}
/* 72 with its rule, the design's: the 46px Next (drawn 40) between 13 and 11, so the drawn pill
   is 16 from the top and 14 from the right. The bare arrow is 18 from the left edge inside the
   44px it is hit at, and the title starts 12 after it. */
.cshell .chead{display:flex;align-items:center;gap:12px;padding:13px 11px 11px 18px;border-bottom:2px solid var(--rule-head)}
.cshell .chead .back{width:44px;height:44px;flex:none;border:0;background:none;color:var(--color-text);display:grid;place-items:center;cursor:pointer;
  margin:0 -13px}
/* The door and the kind are one button, because they are one question asked twice: the door as the
   title, the kind as the pill beside it with the chevron that says it opens. */
.cshell .chead .kind{flex:1;min-width:0;display:flex;align-items:baseline;gap:8px;border:0;background:none;
  color:var(--color-text);font:inherit;cursor:pointer;padding:0;text-align:left}
.cshell .chead div.kind{cursor:default}
.cshell .chead .kind b{flex:none;font-family:var(--font-heading);font-weight:800;font-size:20px;letter-spacing:-.02em;
  line-height:1.2;white-space:nowrap}
.cshell .chead .kind span{flex:0 1 auto;min-width:0;display:inline-block;padding:4px 8px;border-radius:14px;background:var(--surface-1);
  font-family:var(--font-heading);font-weight:800;font-size:10px;line-height:12px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cshell .chead .kind span svg{display:inline-block;vertical-align:-1px;margin-left:3px}
/* Under 340 the title never gives way, so the pill beside it is what runs out: FRAGE came down to
   "F…" and FOTOGRAFI to "FOTOG…". There the pill keeps only its chevron. The word stays in the
   button for anything that reads it, and the screen below says which kind this is. */
@media (max-width:340px){
  .cshell .chead .kind span{font-size:0;letter-spacing:0;padding:4px 7px}
  .cshell .chead .kind span svg{margin-left:0}
}
/* Feeling's two kinds, side by side under the header: the track on the surface, the one you are on
   drawn in the selected chip's colours inside the 44px each half is hit at. */
.cshell .feelseg{flex:none;display:grid;grid-template-columns:1fr 1fr;height:44px;margin:14px 18px 6px;
  border-radius:16px;background:var(--surface-1)}
.cshell .feelseg button{height:44px;min-width:0;padding:0 6px;border:4px solid transparent;border-radius:16px;
  background:none;background-clip:padding-box;color:var(--text-2);cursor:pointer;
  font-family:var(--font-heading);font-weight:800;font-size:13px;line-height:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cshell .feelseg button.on{background-color:var(--sel-bg);color:var(--sel-fg)}
/* 19px/800 and not a pixel less: #f3f2f2 on the accent measures 3.76:1, which clears the
   large-text allowance only from 18.66px bold. Nothing smaller is ever set on a red fill. */
.cshell .chead .post{flex:none;min-height:46px;padding-inline:15px;font-family:var(--font-heading);
  font-weight:800;font-size:19px;letter-spacing:.04em;text-transform:uppercase;text-align:left}
.cbody{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:16px 18px 20px}
/* Under Feeling's segmented control, whose own margin is the space above the label row. */
.cshell[data-kind="number"] .cbody{padding-top:0}
/* A view that lays itself out as bands takes the whole body and its own padding, and nothing in
   it scrolls: if a kind does not fit, something comes out of it rather than a scrollbar going in. */
.cbody.fit{display:flex;flex-direction:column;padding:0;overflow:hidden}
/* The second way to change kind, in thumb reach, for when you notice halfway through. */
/* Where it goes: a sentence at the foot, not a control at the top demanding an answer first. */
/* The commit, at the bottom of the screen, where a thumb already is.
   It sat in the header beside the kind for one release and that was the wrong end of a phone: the
   top right corner is the one place a hand holding a phone cannot reach without regripping it, and
   it is the corner the one button that sends something was in. */
.kindlist{position:fixed;inset:0;z-index:60;background:rgba(0,0,0,.34);display:flex;align-items:flex-start;justify-content:flex-start}
/* A menu, drawn as a card raised off the screen: the bars' colour, 14px corners, a shadow and no
   edge; each kind a row, the one you are on in the accent's text colour. */
.kindlist .body{margin:64px 0 0 12px;min-width:184px;background:var(--bar);border:0;border-radius:var(--radius-md);
  box-shadow:0 10px 30px rgba(0,0,0,.28),0 0 0 1px var(--rule);padding:6px}
.kindlist .body button{display:block;width:100%;min-height:44px;padding:0 12px;border:0;border-radius:10px;background:none;
  color:var(--color-text);font:inherit;font-family:var(--font-heading);font-size:15px;font-weight:800;text-align:left;cursor:pointer}
.kindlist .body button:active{background:var(--surface-1)}
.kindlist .body button.on{color:var(--accent-text);background:var(--accent-tint)}

/* ─── Moment · Photo ───────────────────────────────────────────────────── */
/* Nothing in here shrinks below what is in it.
   Both of these used to: the view was `flex:1;min-height:0` and the row `flex:0 1 auto;min-height:0`,
   so when the picture plus the caption plus the library button came to more than the screen, the
   flexbox took the difference out of the *row* — and the row shrinking does not shrink the picture,
   which is sized by its own proportions. The picture went on being its own height inside a box half
   that tall and was simply drawn over the caption, the line about a second photo and the button
   under them, all of which showed around its edges. A photograph too tall for the screen scrolls,
   like everything else too tall for a screen: .cbody is a scroller already. */
/* Nothing taken yet: a way into the camera, at the size of a way in rather than of a photograph.
   The library button sits under it and the chips for Voice and Place under that, so the screen is
   three ways on instead of one empty frame. */
/* A second photograph lays itself out beside the first. There is no layout to choose, which is
   why this is a cell and not a screen. */
.photoview .say,.gamelist .say{font-size:11px;line-height:1.4;color:var(--color-neutral-700);margin:0}
/* The tools that stopped being post types, where they belong: on the shot. */
.onshotsheet{position:fixed;inset:0;z-index:70;background:var(--color-bg);display:flex;flex-direction:column;
  padding-top:env(safe-area-inset-top)}
.onshotsheet .top{display:flex;align-items:center;gap:8px;padding:8px 12px 8px 7px;border-bottom:2px solid var(--rule-head)}
.onshotsheet .top b{flex:1;min-width:0;font-family:var(--font-heading);font-weight:800;font-size:20px;letter-spacing:-.02em}
/* A bare way back, as every composer's is: it is an icon-btn without .btn, so it was wearing the
   browser's own 2px outset edge — drawn round since stage 1. */
.onshotsheet .top .icon-btn{display:grid;place-items:center;border:0;background:none;cursor:pointer}
.onshotsheet .canvasbox{flex:1;min-height:0;display:grid;place-items:center;overflow:hidden;background:var(--color-surface);position:relative}
.onshotsheet canvas{display:block;max-width:100%;max-height:100%;touch-action:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}
.onshotsheet .tools{flex:none;display:flex;align-items:center;gap:8px;padding:10px 14px calc(10px + env(safe-area-inset-bottom));
  border:0;background:var(--bar);overflow-x:auto;scrollbar-width:none}
.onshotsheet .tools::-webkit-scrollbar{display:none}
/* Filled tiles with 14px corners; the pen in use is the light chip, its colour a round swatch. */
.onshotsheet .tools button{flex:none;min-height:44px;min-width:44px;border:0;border-radius:var(--radius-md);
  background:var(--surface-1);color:var(--color-text);font:inherit;font-family:var(--font-heading);font-size:13px;font-weight:800;cursor:pointer;display:grid;place-items:center;padding:0 12px}
.onshotsheet .tools button.on{background:var(--sel-bg);color:var(--sel-fg)}
/* A thin ring of the muted ink round every swatch, so the black pen still reads on the dark surface. */
.onshotsheet .tools button i{width:22px;height:22px;border-radius:50%;display:block;box-shadow:0 0 0 1.5px var(--muted)}
.onshotsheet .tools button.on i{box-shadow:0 0 0 1.5px var(--sel-fg)}
.onshotsheet .stickstrip button{padding:0 6px}
.onshotsheet .stickstrip img{width:34px;height:34px;object-fit:contain;display:block}
/* Sideways and nothing else: no double-tap zoom on a strip where two quick taps are two stickers. */
.onshotsheet .stickstrip{touch-action:pan-x}
/* Your own stickers (mystickers.js): first in the strip, after the "+" that adds one. A long press
   on one offers to delete it, so the phone's own callout and selection are kept off them. */
.onshotsheet .stickstrip .stkplus{color:var(--text-2)}
.stkmine{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}
.stkmine img{-webkit-user-drag:none;pointer-events:none}
/* The sheet that adds one or deletes one, drawn as the other sheets are. The keyboard's way in is a
   rich field (never plaintext-only, or an iPhone offers it no stickers), with its line as a placeholder. */
.stksheet .sheet-body{padding:21px 18px 8px;gap:12px}
.stksheet .sheet-body p{margin:0;font-size:14px;line-height:1.5;color:var(--text-2)}
.stksheet .sheet-body .h2{margin:0;font-family:var(--font-heading);font-weight:800;font-size:24px;line-height:1.1;letter-spacing:-.02em}
.stksheet .sheet-body .btn{margin:4px 0 0;border-radius:var(--radius-md);font-weight:800;gap:8px}
.stksheet .sheet-foot{padding:6px 18px 14px;border:0}
.stksheet .sheet-foot .btn{min-height:48px;padding:0 16px;border-radius:var(--radius-md);background:var(--surface-1);font-weight:800}
.stksheet .stkcatch{min-height:56px;padding:16px;border-radius:var(--radius-md);background:var(--surface-1);color:var(--text);
  font-size:16px;line-height:1.4;outline:none;-webkit-user-select:text;user-select:text;overflow-wrap:anywhere}
.stksheet .stkcatch:focus{box-shadow:0 0 0 2px var(--text-2)}
.stksheet .stkcatch:empty::before{content:attr(data-ph);color:var(--muted)}
.stksheet .stkcatch img{max-height:48px}
.stksheet .sheet-body .stknote{min-height:1.5em;font-size:13px}
.stksheet .stkbig{display:block;width:120px;height:120px;object-fit:contain;margin:0 auto}
/* The box the picture sits in takes every finger while stickers are being placed: a pinch often has
   one of them off the picture. Nothing in it scrolls, so it is named in native.js's scrollerAt. */
.onshotsheet .canvasbox.stickfield{touch-action:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}
/* The picture at the size that fits, and the stickers on a stage laid exactly over it. The stage is
   its own stacking context, so a sticker lifted to the top for a drag is on top of the stickers and
   of nothing else; the bin sits on the picture under the stage, so a sticker dragged onto it is
   seen going in. It cuts a sticker off at the picture's edge, because that is where the posted
   picture cuts it. */
.onshotsheet .shotwrap{position:relative;max-width:100%;max-height:100%}
.onshotsheet .shotwrap canvas{position:absolute;inset:0;width:100%;height:100%;max-width:none;max-height:none}
/* The photograph as the composer shows it: the file itself, at the screen's own pixels. The ink is a
   clear canvas over it, and the stickers a stage over that. */
.onshotsheet .shotwrap .shotimg{position:absolute;inset:0;display:block;width:100%;height:100%;max-width:none;max-height:none;
  object-fit:fill;pointer-events:none;-webkit-user-drag:none;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
.stickstage{position:absolute;inset:0;z-index:1;isolation:isolate;touch-action:none;overflow:hidden;
  -webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}
.stickstage.still{pointer-events:none}
.stickstage .stk{position:absolute;left:50%;top:50%;width:28%;height:auto;max-width:none;display:block;
  transform:translate(-50%,-50%);transform-origin:50% 50%;
  -webkit-touch-callout:none;-webkit-user-drag:none;-webkit-user-select:none;user-select:none}
/* The picked one: a hairline of white with a dark edge, drawn the same thickness at any size. */
.stickstage .stk.on{outline:calc(1.5px / var(--s, 1)) solid #fff;box-shadow:0 0 0 calc(2.5px / var(--s, 1)) rgba(0,0,0,.3)}
/* Its ×: drawn 24, hit at 44, on the photo's overlay chip. Gone while a finger is moving things. */
.stickstage .stkx{position:absolute;z-index:2;width:44px;height:44px;margin:0;padding:0;border:0;background:none;
  transform:translate(-50%,-50%);display:grid;place-items:center;color:#fff;cursor:pointer;touch-action:manipulation}
.stickstage .stkx::before{content:'';position:absolute;left:10px;top:10px;width:24px;height:24px;border-radius:50%;
  background:rgba(28,26,25,.72);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);box-shadow:0 0 0 1.5px rgba(255,255,255,.85)}
.stickstage .stkx svg{position:relative}
.stickstage.moving .stkx{visibility:hidden}
/* The bin, at the foot of the picture itself (not of the box it sits in, which is taller than a
   picture lying down) while a sticker is being dragged: a round button on the surface, shown and
   grown by motion.js and never touched itself — the finger is judged by where it is. */
.onshotsheet .stktrash{position:absolute;left:0;right:0;bottom:16px;margin:0 auto;width:48px;height:48px;border-radius:50%;
  background:var(--surface-1);color:var(--text);display:grid;place-items:center;pointer-events:none;opacity:0;
  box-shadow:0 2px 10px rgba(0,0,0,.28)}
/* The draft's stickers over the composer's own picture: the same box and zoom as the picture, and
   inside it the part the photograph fills. `.photoframe img` sizes every picture in the frame to
   the whole frame, so each of these says its own size back. */
.photoframe .stuckon{position:absolute;inset:0;pointer-events:none;transform-origin:center}
.photoframe .stuckon i{position:absolute;display:block;overflow:hidden}
.photoframe .stuckon canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.photoframe .stuckon img{position:absolute;inset:auto;height:auto;max-width:none;max-height:none;object-fit:fill;transform-origin:50% 50%}

/* ─── Together · Game ──────────────────────────────────────────────────── */
/* No POST on this one view: playing is posting, so a row opens its game rather than choosing it. */
.gamelist{display:flex;flex-direction:column;gap:2px}
.gamelist .grow{min-height:74px;display:flex;align-items:center;gap:12px;padding:0 4px;border:0;
  border-bottom:1px solid var(--color-divider);background:none;color:var(--color-text);font:inherit;
  cursor:pointer;text-align:left}
.gamelist .grow .body{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.gamelist .grow .body b{font-family:var(--font-heading);font-weight:800;font-size:17px}
.gamelist .grow .body i{font-style:normal;font-size:12px;color:var(--color-neutral-700)}
.gamelist .kept{font-size:12px;color:var(--color-accent-800);margin:8px 0 0}

/* Link's last row: the same intent by another route. Dashed, because it is a way out of this view
   rather than a control in it. */

/* The word about a feeling, where the feeling is shown. */
.emonote{font-size:12px;line-height:1.4;color:var(--jr-photo-ink);margin:6px 0 0;text-wrap:pretty}
.detail .hero-emo .emonote{color:var(--color-text);font-size:14px;margin-top:10px}

/* ─── one big feed ──────────────────────────────────────────────────────── */
/* From the row under the kind chips on Home, and at #/feed. Everything here is scoped under
   .feed — the class kept its demo name until the cleanup round that renamed it — so it cannot
   reach the real spread, and the whole block lifts out in one piece when the demo has done its
   job. It reuses the day sheet, the rail and the tiles exactly as the journal draws them. */
.feed{display:flex;flex-direction:column;height:100%}
.fdhead{display:flex;align-items:center;gap:7px;padding:12px 14px 8px 11px}
.fdhead .h1{flex:1;min-width:0;margin:0;font-size:26px;font-weight:800;letter-spacing:-.03em}
.fdhead .cnt{flex:none;padding:4px 9px;border-radius:var(--radius-md);background:var(--surface-1);font-size:11px;font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;color:var(--text-2);font-variant-numeric:tabular-nums}
.fdnote{padding:0 18px 10px;font-size:12px;line-height:1.45;color:var(--muted)}
.feed .feedscroll{flex:1;min-height:0}
/* One card to a row, the width of the column: the mosaic's tiles, not its grid. A deck needs the
   width to be dragged across, and every row here is one post already (see unpair). */
.feed .entry{display:block;padding:0 14px 14px}
.feed .econt{min-width:0}
.feed .cards{display:block;min-width:0}
/* The one thing a feed adds to a spread: which room this came from, on the line that already
   says who and when. Not on the picture — a stamp over a photograph has nowhere to wrap, and a
   journal called "Summer crew 2026" is 167px of nowrap before the second name. */
.feed .fdline{display:flex;align-items:center;gap:8px;min-height:24px;padding:0 4px 6px}
.jstamp{flex:none;display:inline-flex;align-items:center;gap:6px;max-width:100%;padding:2px 0;
  background:none;border:0;font:inherit;color:var(--text-2);cursor:pointer}
.jstamp .dot{flex:none;width:8px;height:8px;border-radius:50%;opacity:.9}
.jstamp .nm{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:10px;font-weight:800;letter-spacing:.1em;text-transform:uppercase}
/* A post that went to five journals, as one deck of five cards rather than five cards in a row.
   The five filled a phone screen on their own and the one with a comment waiting was fourth. */
.feed .entry.deck .econt{padding-bottom:6px}
/* The line that says what this is. Without it a deck is a card that happens to have edges behind
   it, and nobody would know there were four more rooms under their thumb. */
.feed .alsoline{display:flex;align-items:center;gap:6px;padding:0 4px 7px;
  font-size:11px;line-height:1.3;color:var(--muted)}
.feed .alsoline svg{flex:none;opacity:.7}
/* The stage. `pan-y` is set on the element in the markup as well, where it belongs with the
   handlers that depend on it, and repeated here so a reader of either one finds it. */
.feed .deckstage{position:relative;touch-action:pan-y;outline:0;border-radius:var(--radius-md)}
.feed .deckstage:focus-visible{outline:2px solid var(--color-text);outline-offset:3px}
/* One edge for everything that moves sideways across the deck: the card under a finger and the copy
   that leaves after it are both clipped at the same one (the window below). When the dragged card was free
   and only the leaving copy was clipped, at the stage's own box, the strip of card hanging past that
   box vanished in the frame the finger lifted. A clip-path and not `overflow`, so the stage does not
   become a scroll container. The insets leave everything drawn at rest alone: 6px is the focus ring
   (2px at 3px out), 10px right and below is the far back sheet, which sits 8px down and across. The
   ring already lies over the rail's rule on the left, so a card in motion crosses it too. */
.feed .deckstage{clip-path:inset(-6px -10px -10px -6px round var(--radius-md))}
/* And inside it the window the moving card and the leaving copy are seen through, which does not
   move. The stage's edge is 6px outside the card and its corners are up beside the journal's
   stamp, so a tile crossing it was cut by a straight line: a square corner at the top and bottom
   of every slide. The window is cut round the tile instead — its own 14px corners plus the 2px of
   the unread ring, so nothing drawn at rest is cut — joined to a band across the top for the stamp,
   which is words and has no corner to show. The band is the stamp line's height, pinned here
   (19px of stamp and 6 under it) so the window's top always meets the tile's. A polygon and not
   `inset() round`, which is one rectangle and cannot be both. */
.feed .deckstage{--stamp:25px}
.feed .deckwin>.deckcard>.fdline{height:var(--stamp)}
.feed .deckwin{position:relative;clip-path:polygon(
  -6px -6px, calc(100% + 6px) -6px, calc(100% + 6px) calc(var(--stamp) - 2px),
  calc(100% - 14px) calc(var(--stamp) - 2px), calc(100% - 9.86px) calc(var(--stamp) - 1.45px),
  calc(100% - 6px) calc(var(--stamp) + .14px), calc(100% - 2.69px) calc(var(--stamp) + 2.69px),
  calc(100% - .14px) calc(var(--stamp) + 6px), calc(100% + 1.45px) calc(var(--stamp) + 9.86px),
  calc(100% + 2px) calc(var(--stamp) + 14px),
  calc(100% + 2px) calc(100% - 14px), calc(100% + 1.45px) calc(100% - 9.86px),
  calc(100% - .14px) calc(100% - 6px), calc(100% - 2.69px) calc(100% - 2.69px),
  calc(100% - 6px) calc(100% - .14px), calc(100% - 9.86px) calc(100% + 1.45px),
  calc(100% - 14px) calc(100% + 2px),
  14px calc(100% + 2px), 9.86px calc(100% + 1.45px), 6px calc(100% - .14px), 2.69px calc(100% - 2.69px),
  .14px calc(100% - 6px), -1.45px calc(100% - 9.86px), -2px calc(100% - 14px),
  -2px calc(var(--stamp) + 14px), -1.45px calc(var(--stamp) + 9.86px), .14px calc(var(--stamp) + 6px),
  2.69px calc(var(--stamp) + 2.69px), 6px calc(var(--stamp) + .14px), 9.86px calc(var(--stamp) - 1.45px),
  14px calc(var(--stamp) - 2px), -6px calc(var(--stamp) - 2px))}
/* What is under the top card, drawn as the edges of two more sheets. Called `deckback` and not
   `sheet`, which is taken: `.sheet` at the top of this file is the app's modal bottom sheet, it is
   unscoped, and a back card wearing that name quietly inherited its drop shadow, its `overflow`
   and a 220ms slide-up animation that ran on every one of them. The ground colour is the day
   sheet's own, so what shows is a hairline and nothing else — and the card is given the same
   ground so it covers them rather than letting them show through its gaps.
   Straight, not fanned. A card turned even half a degree is painted wider than it is laid out and
   charges the side gutters for the corner it throws out, which is why the prints stopped being
   crooked; 4px and 8px stay inside the 12px the column already has. They are behind the tile and
   not the stamp above it: a stack of tiles, and the window's corners never uncover their edges. */
.feed .deckstage .deckback{position:absolute;inset:var(--stamp) 0 0;pointer-events:none;border-radius:var(--radius-md);
  background:var(--page);border:1px solid var(--rule);
  display:flex;align-items:center;justify-content:space-between;padding:0 14px;overflow:hidden}
/* The two rooms either side, waiting under the card. Set in the stamp's own letters so what is
   uncovered reads as the same kind of thing as the stamp that will replace it. Named `toprev` and
   `tonext` rather than `back` and `on`, which both already mean something else in this file — `on`
   is "the selected one" on eight other controls. */
.feed .deckstage .deckback .to{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:10px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:var(--muted)}
.feed .deckstage .deckback.near{transform:translate(4px,4px)}
.feed .deckstage .deckback.far{transform:translate(8px,8px);opacity:.55}
.feed .deckcard{position:relative;background:var(--page);border-radius:var(--radius-md);
  transition:transform .19s cubic-bezier(.2,.7,.3,1)}
/* Following a finger is the one time it must not ease: a transition on a transform being written
   every frame lags the thumb by its own duration. */
.feed .deckcard.dragging{transition:none}
/* A turn, as a slide. The new copy is the live card the moment the deck turns; what moves is a dead
   clone of the old one, laid over it and sent out of the frame the way the deck went. The host is
   always there and empty at rest, clips nothing of its own — the window above is the one the
   dragged card is cut at too — and takes no pointer, so a finger mid-slide lands on the copy
   underneath. Same curve as the snap-back. A timer takes the clone away; nothing listens for
   transitionend. */
.feed .deckstage .deckfly{position:absolute;inset:0;pointer-events:none}
.feed .deckghost{position:absolute;top:0;left:0;width:100%;background:var(--page);border-radius:var(--radius-md);
  pointer-events:none;transition:transform .22s cubic-bezier(.2,.7,.3,1)}
/* One mark per journal: where you are, how many there are, and which of the others have somebody
   waiting in them — the only place the four hidden cards still get to say so.
   The marks are 6px and the buttons around them are 24px, because a 6px target is not one. */
.feed .deckbar{display:flex;align-items:center;gap:10px;padding:10px 4px 0}
.feed .deckbar .dots{display:flex;align-items:center;gap:3px;min-width:0;flex-wrap:wrap}
.feed .deckdot{width:16px;height:24px;flex:none;padding:0;border:0;background:none;cursor:pointer;
  display:grid;place-items:center}
.feed .deckdot::before{content:'';width:6px;height:6px;border-radius:3px;background:var(--surface-3)}
.feed .deckdot.soft::before{background:color-mix(in srgb,var(--color-accent) 55%,transparent)}
.feed .deckdot.loud::before{background:var(--color-accent)}
/* Where you are is the tall one — a difference in shape rather than only in ink, so it survives
   being the accent colour already for another reason. */
.feed .deckdot.on::before{width:6px;height:14px;background:var(--color-text)}
.feed .deckdot.on.loud::before{background:var(--color-accent)}
.feed .deckbar .of{flex:none;margin-left:auto;padding:5px 9px;border-radius:12px;background:var(--surface-1);font-size:10px;font-weight:800;
  letter-spacing:.1em;text-transform:uppercase;color:var(--text-2);font-variant-numeric:tabular-nums}

/* ── The evening page (10.6.0, admins first) ─────────────────────────────────
   Every class here is new and starts `ev`, grepped first; the questions are in Caveat 700, the one
   other place it is used beside the day's weekday. */
/* The page as a post: on a tile, in the post, and as the preview on the last card. */
.evpage{display:flex;flex-direction:column;gap:10px;min-width:0}
.evpage .evhd{display:flex;align-items:baseline;gap:10px}
.evpage .evhd .k{flex:1;min-width:0;font-size:10px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--accent-text)}
.evpage .evhd .hw{flex:none;font-family:'Caveat',cursive;font-weight:700;font-size:22px;line-height:1;color:var(--hand)}
.evpage .evqa{display:flex;flex-direction:column;gap:3px;min-width:0}
.evpage .ql{font-size:10px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);line-height:1.35}
.evpage .qa{margin:0;font-size:15px;line-height:1.4;color:var(--text);white-space:pre-wrap;overflow-wrap:anywhere;
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;overflow:hidden}
.evpage.full .qa{display:block;-webkit-line-clamp:none;font-size:17px;line-height:1.45}
.evpage .evmood{display:flex;align-items:center;gap:10px}
.evpage .evmood .ql{flex:none}
.evpage .evmood .evtrack{flex:1;min-width:0;height:6px;padding:0;border:0;border-radius:3px;background:var(--surface-2);overflow:hidden;position:relative}
.evpage .evmood .evtrack i{position:absolute;left:0;top:0;bottom:0;border-radius:3px;background:var(--accent)}
.evpage .evmood b{flex:none;font-family:var(--font-heading);font-weight:800;font-size:16px;line-height:1}
.evpage .evmood b i{font-style:normal;font-size:10px;font-weight:600;color:var(--muted);margin-left:2px}
.evpage .evpic{border-radius:10px;overflow:hidden}
.detail .hero-evening{margin:4px 14px 0;padding:16px;border-radius:var(--radius-md);background:var(--surface-1)}

/* Home: the page is waiting. A row like the feed's, with the count under it, quietly. */
.evway{display:flex;align-items:center;gap:10px;width:calc(100% - 36px);margin:0 18px;
  min-height:44px;padding:0;border:0;border-bottom:1px solid var(--rule);
  background:none;font:inherit;color:var(--color-text);cursor:pointer;text-align:left}
.evway .w{flex:1;min-width:0;font-size:13px;font-weight:800}
.evway svg{flex:none}
.evway svg:first-child{color:var(--accent-text)}
.evcount{margin:0 18px;padding:7px 0 4px;font-size:12px;color:var(--muted)}

/* The writing flow: a bar of four, the card, and two buttons under it. */
.screen.evening{background:var(--page);overscroll-behavior:none}
.evening .evtop{flex:none;display:flex;align-items:center;gap:10px;padding-left:18px;padding-right:8px}
.evening .evbar{flex:1;display:flex;gap:4px;min-width:0;padding:16px 0}
.evening .evbar i{flex:1;height:3px;border-radius:2px;background:var(--surface-2)}
.evening .evbar i.done{background:var(--text)}
.evening .evbar i.on{background:var(--accent)}
.evening .evx{width:44px;height:44px;flex:none;touch-action:manipulation;border:0;background:none;color:var(--text);display:grid;place-items:center;cursor:pointer}
.evening .evstage{flex:1;min-height:0;position:relative;overflow:hidden}
.evening .evcard{position:absolute;inset:0;overflow-y:auto;padding:14px 22px 18px;display:flex;flex-direction:column;gap:14px}
/* pan-y written on the card and the field as well as the stage: each of them scrolls, a scroller
   starts touch-action afresh, and a sideways drag that began on one was the browser's pan — a
   pointercancel on the first move — instead of the swipe between cards. */
.evening .evcard,.evening .evans{touch-action:pan-y}
.evening .evn{font-size:10px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
.evening .evask{margin:0;font-family:'Caveat',cursive;font-weight:700;font-size:38px;line-height:1.08;color:var(--text);text-wrap:balance}
.evening .evans{flex:1;min-height:150px;max-height:50vh;width:100%;resize:none;border:0;border-radius:var(--radius-md);
  padding:14px 16px;background:var(--surface-1);color:var(--text);font:inherit;font-size:17px;line-height:1.45}
.evening .evans::placeholder{color:var(--placeholder)}
.evening .evfeel{flex:none;padding:0}
.evening .evfeel .srow{max-height:none;flex:none}
.evening .evpick{display:flex;align-items:center;gap:10px;min-height:56px;padding:0 16px;border:0;border-radius:var(--radius-md);
  background:var(--surface-1);color:var(--text);font:inherit;cursor:pointer;text-align:left}
.evening .evpick span{flex:1;font-weight:800;font-size:14px}
.evening .evpick i{font-style:normal;font-size:12px;color:var(--muted)}
.evening .evphoto{position:relative;border-radius:var(--radius-md);overflow:hidden;background:var(--surface-1)}
.evening .evphoto img{display:block;width:100%;max-height:38vh;object-fit:cover}
.evening .evunpick{position:absolute;top:6px;right:6px;width:44px;height:44px;border:0;background:none;display:grid;place-items:center;cursor:pointer;color:#fff}
.evening .evunpick::before{content:'';position:absolute;inset:8px;border-radius:50%;background:rgba(0,0,0,.55)}
.evening .evunpick svg{position:relative}
.evening .evpreview{padding:16px;border-radius:var(--radius-md);background:var(--surface-1)}
.evening .evbtns{flex:none;display:flex;gap:10px;padding:10px 18px calc(14px + env(safe-area-inset-bottom))}
/* No double-tap zoom on these: two quick taps are two cards, and native.js lets their touchend through. */
.evening .evbtns .btn{flex:1;min-height:48px;touch-action:manipulation}
.evening .evbtns .evskip{color:var(--text-2)}
.evsharing .cgo{flex:none;height:46px;min-height:46px;padding:0 18px;border:3px solid transparent;border-radius:17px;
  background-color:var(--surface-1);background-clip:padding-box;color:var(--disabled);cursor:pointer;
  font-family:var(--font-heading);font-weight:800;font-size:15px;line-height:1}
.evsharing .cgo.on{background-color:var(--accent-fill);color:var(--on-accent)}
.evsharing .bar button{touch-action:manipulation}

/* Me → Evening page: the settings sheet. */
.evsheet .evseg{display:flex;gap:4px;padding:4px;border-radius:14px;background:var(--surface-1)}
.evsheet .evseg button{flex:1;min-height:40px;border:0;border-radius:10px;background:none;color:var(--text-2);font:inherit;font-weight:800;cursor:pointer}
.evsheet .evseg button.on{background:var(--sel-bg);color:var(--sel-fg)}
.evsheet .evfield{display:flex;flex-direction:column;gap:6px}
.evsheet .evfield .lbl{margin:0;font-size:12px;font-weight:700;color:var(--muted)}
.evsheet .evtime,.evsheet .evjournal{min-height:44px}
.evsheet .evdays{display:flex;gap:4px}
.evsheet .evdays button{flex:1;min-width:0;min-height:44px;padding:0;border:0;border-radius:10px;background:var(--surface-1);
  color:var(--text-2);font:inherit;font-size:13px;font-weight:700;cursor:pointer}
.evsheet .evdays button.on{background:var(--sel-bg);color:var(--sel-fg)}
.evsheet .evqs{display:flex;flex-direction:column}
.evsheet .evq{display:flex;align-items:center;gap:10px;min-height:48px;padding:6px 0;border:0;border-bottom:1px solid var(--rule);
  background:none;color:var(--text);font:inherit;font-size:14px;text-align:left;cursor:pointer;width:100%}
.evsheet .evq .w{flex:1;min-width:0}
.evsheet .evq i{font-style:normal;font-size:11px;color:var(--muted)}
.evsheet .evq.fixed{cursor:default}
.evsheet .evq .tk{width:22px;height:22px;flex:none;border-radius:6px;background:var(--surface-1);box-shadow:inset 0 0 0 1.5px var(--muted);
  display:grid;place-items:center;color:var(--sel-fg)}
.evsheet .evq .tk.on{background:var(--sel-bg);box-shadow:none}
.evsheet .evdrop{width:44px;height:44px;flex:none;border:0;background:none;color:var(--muted);display:grid;place-items:center;cursor:pointer}
.evsheet .evadd{display:flex;gap:8px;padding-top:8px}
.evsheet .evadd .input{flex:1;min-width:0;min-height:44px}
