/* shelfstackd: the look every page shares. The numbers are here once, as variables; a page's own <style> uses them
   and adds only what that page alone needs. Black ink on white paper, Courier Prime, one 950px column. */
:root{
  --paper:#FFFFFF; --ink:#000000; --grey:#6B6B6B; --hair:#D9D9D9; --wash:#F3F3F3;
  --mono:"Courier Prime","Courier New",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;

  /* one column: every page's content, and the top bar's, sit in it */
  --col:950px; --gutter:24px;

  /* type (Courier Prime runs wide, so it stays small) */
  --fs-body:13px;      /* text */
  --fs-title:22px;     /* a page's title: weight 400, in its own case */
  --fs-dialog:16px;    /* a sheet's or dialog's title */
  --fs-section:12px;   /* section headings: uppercase, grey, a hairline under */
  --fs-nav:12px;       /* the top bar's links: uppercase, weight 500 */
  --fs-tab:13px;       /* tabs: in their own case, the current one black with a 1px underline */
  --fs-card:12px;      /* a shelf's name under its card */
  --fs-small:11px;     /* @username under a card, notes, small print */
  --fs-btn:11px;       /* buttons: uppercase, weight 600 */
  --fs-label:10px;     /* tiny labels: uppercase, grey */
  --fs-stat:20px;      /* the numbers on a profile */
  --fs-logo:18px; --logo-track:.18em;
  --track:1px;         /* letter-spacing of uppercase nav links, section headings and labels */

  /* spacing: only these */
  /* one spacing scale, in steps of 8px (4px only for the tightest, inside a thing): every margin, padding and gap is
     one of these. Off it on purpose: 1px where borders overlap, the 2px between spines (they stand as books do), and
     the invisible padding that makes a small thing 44px to press */
  --s1:4px; --s2:8px; --s4:16px; --s5:24px; --s6:40px;

  --radius:3px;
  --btn-pad:8px 16px;
  --cards:6; --card-gap:16px;   /* shelves listed: six across the column (145px each), 16px apart */
  --card:150px;                 /* a card on its own (in the feed) is that wide too */
  --cover:72px;                 /* a logged film's or book's cover, with its caption beside it (2:3, so 108px tall) */
}
@media (max-width:820px){ :root{--cards:4} }
@media (max-width:640px){ :root{--gutter:16px; --fs-logo:15px; --cards:3} }

*{box-sizing:border-box}
[hidden]{display:none!important}
html{background:var(--paper)}
body{margin:0;background:var(--paper);color:var(--ink);font:400 var(--fs-body)/1.55 var(--mono)}
a{color:inherit}
:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
p{margin:0 0 var(--s4)}
.grey{color:var(--grey)}

/* the column */
main{width:min(100% - 2*var(--gutter), var(--col));margin-inline:auto;padding-top:var(--s5)}

/* ---------- type ---------- */
h1{font-size:var(--fs-title);font-weight:400;line-height:1.3;letter-spacing:0;margin:0 0 var(--s5);overflow-wrap:anywhere}
/* the one section label: a section's heading (h2), or .seclabel where the label isn't a heading (the builder's Style,
   which opens and shuts). 12px capitals in grey, a hairline under, with room on its right for a small link (See all)
   or a count. Nothing else is set this way */
h2,.seclabel{display:flex;gap:var(--s4);align-items:baseline;font-size:var(--fs-section);font-weight:400;line-height:1.5;text-transform:uppercase;letter-spacing:var(--track);color:var(--grey);
  border-bottom:1px solid var(--hair);padding-bottom:var(--s1);margin:0 0 var(--s4)}
h2 small,.seclabel small{font-size:inherit;font-weight:400;letter-spacing:0}
h2 .more,.seclabel .more{margin-left:auto;font:400 var(--fs-small) var(--mono);letter-spacing:var(--track);text-transform:uppercase;color:var(--grey);background:none;border:0;padding:0;text-decoration:none;cursor:pointer}
h2 .more:hover,h2 .more:focus-visible,.seclabel .more:hover,.seclabel .more:focus-visible{color:var(--ink)}
.lbl{font-size:var(--fs-label);line-height:1.5;color:var(--grey);text-transform:uppercase;letter-spacing:var(--track)}
.note{font-size:var(--fs-small);color:var(--grey)}
.note:empty{display:none}
.note.warn{color:var(--ink);font-weight:700}
em.pro,.tag{font-style:normal;font-weight:700;font-size:9px;border:1px solid currentColor;padding:0 var(--s1);letter-spacing:.04em;text-transform:uppercase}

/* ---------- buttons: three looks, no more. Solid black (.btn.primary) for what a screen is for; outlined (.btn.line:
   black on white, a 1px black line round it, the same box as the solid one) for a second thing to make that has to read as a
   button (+ New shelf); everything else is a plain text action (.btn without primary, and .dash): small, grey, black
   on hover. A state ("Following", "In Up next", "Main shelf") is grey text that isn't pressed. Follow is solid black until it's pressed; then it says
   Following in grey, and Unfollow when the pointer is on it. In their own case (sentence case): only the bar's places,
   section headings and the tiny labels are in capitals ---------- */
.btn{display:inline-block;font:600 var(--fs-btn)/1.35 var(--mono);text-align:center;text-decoration:none;white-space:nowrap;
  background:none;color:var(--grey);border:0;border-radius:var(--radius);padding:var(--s2) 0;cursor:pointer}
.btn:hover:not(:disabled),.btn:focus-visible{color:var(--ink)}
.btn.primary,.btn.follow:not([aria-pressed="true"]){background:var(--ink);color:var(--paper);border-color:var(--ink);padding:var(--btn-pad)}
.btn.primary:hover:not(:disabled),.btn.follow:not([aria-pressed="true"]):hover:not(:disabled){background:#222;color:var(--paper)}
.btn.line{display:inline-flex;align-items:center;justify-content:center;gap:var(--s1);background:var(--paper);color:var(--ink);box-shadow:inset 0 0 0 1px var(--ink);padding:var(--btn-pad)}   /* its line drawn inside: the solid one's box */
.btn.line:hover:not(:disabled),.btn.line:focus-visible{background:var(--wash);color:var(--ink)}
.btn.line svg{width:16px;height:16px;flex:none;margin:-1px 0}
.btn.full{width:100%}
.btn:disabled{opacity:.5;cursor:default}
.dash{display:inline-block;background:none;border:0;padding:var(--s2) 0;font:600 var(--fs-btn)/1.35 var(--mono);color:var(--grey);cursor:pointer;text-decoration:none;white-space:nowrap}
/* a state, where an action was ("Main shelf", "On your shelf", "In Up next"): the same box, grey, not pressed. So a
   row of a solid button, text actions and states is one line: one font, size and line-height, 8px above and below,
   no border */
.state{display:inline-flex;align-items:center;gap:var(--s1);font:600 var(--fs-btn)/1.35 var(--mono);color:var(--grey);padding:var(--s2) 0;white-space:nowrap}
.state svg{width:16px;height:16px;flex:none;margin:-1px 0}
.btn,.dash,.state{vertical-align:middle;box-sizing:border-box}
.dash:hover:not(:disabled),.dash:focus-visible{color:var(--ink)}
.dash:disabled{opacity:.5;cursor:default}
/* pressed: every button and text action answers the press itself, at once (before anything is saved): it sinks 1px,
   a solid one goes grey-black, a text one goes black. A slow save says so with a small turning line in place of the
   words (aria-busy, set by Nav.busy()), and the button can't be pressed again until it's done */
:is(.btn,.dash,.tabs button,.badge):active:not(:disabled){transform:translateY(1px)}
.btn.primary:active:not(:disabled),.btn.follow:not([aria-pressed="true"]):active:not(:disabled){background:#333}
:is(.btn,.dash):not(.primary):active:not(:disabled){color:var(--ink)}
:is(.btn,.dash)[aria-busy="true"]{position:relative;color:transparent!important;pointer-events:none}
:is(.btn,.dash)[aria-busy="true"]::after{content:"";position:absolute;top:calc(50% - 6px);left:calc(50% - 6px);width:12px;height:12px;border:2px solid var(--grey);border-right-color:transparent;border-radius:50%;animation:busy .7s linear infinite}
.btn.primary[aria-busy="true"]::after{border-color:var(--paper);border-right-color:transparent}
@keyframes busy{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){ :is(.btn,.dash)[aria-busy="true"]::after{animation-duration:2s} }
/* for a screen reader only */
.vh{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;padding:0}

/* ---------- fields ---------- */
input[type=text],input[type=email],select,textarea{font:400 var(--fs-body) var(--mono);color:var(--ink);background:var(--paper);border:1px solid var(--ink);border-radius:var(--radius);padding:var(--s2) var(--s4);width:100%;min-width:0}
input[type=text]::placeholder{color:#767676}
textarea{resize:vertical;line-height:1.5}
.field{display:grid;gap:var(--s1);min-width:0;border:0;margin:0;padding:0}
.check{display:flex;gap:var(--s2);align-items:center;cursor:pointer}
.check input,.opts input{accent-color:var(--ink);margin:0}

/* ---------- the top bar. Its contents sit in the column; only its bottom line runs the width of the window.
   The places are in one order whoever you are: Feed, Shelves, People, search. Signed in: the logo, you, the places and
   + ADD. Signed out: the logo, the places, SIGN IN and + ADD. Each page has the markup; nav.js runs it. ---------- */
.top{position:sticky;top:env(safe-area-inset-top,0px);z-index:5;background:var(--paper);border-bottom:1px solid var(--hair);display:flex;align-items:center;gap:var(--s1) var(--s5);
  padding:var(--s4) max(var(--gutter), calc((100% - var(--col))/2))}
.top a{text-decoration:none;font-size:var(--fs-nav);font-weight:500;letter-spacing:var(--track);text-transform:uppercase;white-space:nowrap}
.top svg{width:16px;height:16px;display:block;flex:none}
.top .mark{display:flex;align-items:center;gap:var(--s2);font-weight:800;font-size:var(--fs-logo);letter-spacing:var(--logo-track);line-height:1;margin-right:auto;flex:none}
.acct{display:flex;align-items:center;gap:var(--s2);min-width:0;font:400 var(--fs-nav) var(--mono);background:none;border:0;padding:0;color:var(--ink);cursor:pointer}
.acct .ava{width:24px;height:24px;border-radius:50%;border:1px solid var(--ink);background:var(--wash);overflow:hidden;display:grid;place-items:center;font-size:var(--fs-small);text-transform:uppercase;flex:none}
.acct .ava img{width:100%;height:100%;object-fit:cover;display:block}
.acct .who{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}   /* a username is shown as it is; a long one ends in … */
.acct > svg{width:16px;height:16px}
.links{display:flex;gap:var(--s5);align-items:center;flex:none}
.links a{display:flex;align-items:center;padding:var(--s1) 0;border-bottom:1px solid transparent}
.links a[aria-current]{border-bottom-color:var(--ink)}
.signin{flex:none}
/* the bell, the last of the places: signed in, once migration 0009 is there; a black dot while something is unread (nav.js) */
.links .bell{position:relative}
.links .bell svg{width:20px;height:20px}
.links .bell .dot{position:absolute;top:2px;right:-2px;width:8px;height:8px;border-radius:50%;background:var(--ink);border:2px solid var(--paper)}
.links .bell[aria-current]{border-bottom-color:transparent}
.links .bell[aria-current] svg{fill:currentColor}
.addwrap{display:flex;flex:none}
.top .add{display:flex;align-items:center;gap:var(--s1);font-size:var(--fs-btn);font-weight:600;letter-spacing:.04em}
.top .addmore{display:flex;align-items:center;padding:var(--s2);margin-left:-1px;border-radius:0 var(--radius) var(--radius) 0}
.top .addmore.primary{margin-left:0;border-left-color:#5A5A5A}
.top .add svg,.top .addmore svg{width:16px;height:16px}
.addwrap.split .add{border-radius:var(--radius) 0 0 var(--radius)}
/* narrow windows and phones: the logo, you and + on the first row; the places on a second row that scrolls sideways
   inside the bar. The rows are 16px apart, so their middles are 44px apart and a press just under the logo is still
   the logo's, not a place's */
@media (max-width:820px){
  .top{flex-wrap:wrap;padding-bottom:0;row-gap:var(--s4)}
  .links{order:9;flex:0 0 100%;overflow-x:auto;scrollbar-width:none;padding-bottom:var(--s2)}
  .links::-webkit-scrollbar{display:none}
}
@media (max-width:520px){
  .acct .who,.acct > svg{display:none}   /* you are just your photo */
  .top .add span{display:none}           /* + SHELF is just + */
}

/* ---------- tabs ---------- */
/* one line, always: more tabs than fit scroll sideways inside the row, never the page; 16px of room after the last,
   so scrolled to the end it isn't cut off at the edge */
.tabs{display:flex;gap:var(--s5);border-bottom:1px solid var(--hair);overflow-x:auto;overflow-y:hidden;scrollbar-width:none;min-width:0;padding-right:var(--s4)}
.tabs::-webkit-scrollbar{display:none}
.tabs button{flex:none;white-space:nowrap;font:400 var(--fs-tab) var(--mono);background:none;border:0;padding:0 0 var(--s2);margin-bottom:-1px;color:var(--grey);cursor:pointer;border-bottom:1px solid transparent}
.tabs button[aria-selected="true"]{color:var(--ink);border-bottom-color:var(--ink)}
/* on a touch screen a tab is 44px tall itself, its words at the foot over the line (a press area outside it would be
   cut off by the row, which scrolls) */
@media (pointer:coarse){ .tabs button{min-height:44px;min-width:44px;display:inline-flex;align-items:flex-end;justify-content:center} .tabs button::before{display:none} }

/* ---------- shelves, where they're listed: no card and no box. Each is its first spines standing on a thin black line
   (bare.js draws them as the line nears the screen), its name under it, then who made it. Six across the column, four
   or three on a narrower window ---------- */
.thumbs{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(var(--cards),minmax(0,1fr));gap:var(--s4) var(--card-gap)}
.thumbs:empty{display:none}
.thumbs a{display:block;text-decoration:none;min-width:0}
.sl{display:flex;align-items:flex-end;gap:2px;height:96px;border-bottom:1px solid var(--ink);overflow:hidden}
.sl canvas{display:block;flex:none}
/* fewer than three (home's Just shelved): each shelf across the column, all its spines on one long line */
.thumbs.few{grid-template-columns:minmax(0,1fr);gap:var(--s5)}
.thumbs.few .sl{height:160px}
@media (max-width:640px){ .thumbs.few .sl{height:120px} }
.thumbs a:hover .cap,.thumbs a:focus-visible .cap{text-decoration:underline;text-underline-offset:3px}
/* a cover, worn (a log) or clean (Up next): a 1px outline, black under the pointer */
:is(canvas,img):is(.worn,.clean){outline:1px solid var(--hair);outline-offset:-1px}
:is(canvas,img):is(.worn,.clean):hover,:is(a,.cover):hover :is(canvas,img):is(.worn,.clean),a:focus-visible :is(canvas,img):is(.worn,.clean){outline-color:var(--ink)}
.thumbs .cap{display:block;font-size:var(--fs-card);margin-top:var(--s2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.thumbs .by,.thumbs .meta{display:block;font-size:var(--fs-small);color:var(--grey);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ---------- activity: a line for each shelf saved ("@abc shelved my films · 2h"), and the shelf's card under it,
   in line with the text; and for each film or book logged. The feed has them, and a profile's Activity tab. ---------- */
.items{list-style:none;margin:0;padding:0;display:grid;gap:var(--s5)}
.items .item{display:grid;grid-template-columns:32px minmax(0,1fr);gap:var(--s4);align-items:center;min-width:0}
.items .fa{width:32px;height:32px;border-radius:50%;border:1px solid var(--ink);background:var(--wash);overflow:hidden;display:grid;place-items:center;font-size:var(--fs-body);text-transform:uppercase;text-decoration:none;color:var(--ink)}
.items .fa img{width:100%;height:100%;object-fit:cover;display:block}
.items .line{margin:0;min-width:0;overflow-wrap:anywhere}
.items .line a{font-weight:500;text-decoration:none}
.items .line a:hover,.items .line a:focus-visible{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px}
.items .ago{color:var(--grey);font-size:var(--fs-small);font-variant-numeric:tabular-nums;white-space:nowrap}
.items .pic{grid-column:2;width:var(--card)}
/* a film or a book logged ("@abc watched Gummo · today"): its cover, worn (wear.js), small, with the caption beside
   it on every width (a phone too). A shelf saved keeps its card */
.items .line b{font-weight:500}
.items .logbody{grid-column:2;display:flex;gap:var(--s4);align-items:flex-start;min-width:0}
.items .cover{display:block;flex:none;width:var(--cover);line-height:0}
.items .cover canvas{display:block;width:100%;height:auto}
.items .say{margin:0;flex:1 1 0;min-width:0;max-width:56ch;white-space:pre-line;overflow-wrap:anywhere}
/* one person's own lines, on their profile: no photo beside each */
.items.solo .item{grid-template-columns:minmax(0,1fr)}
.items.solo .pic,.items.solo .logbody{grid-column:1}
@media (max-width:640px){
  .items .item{grid-template-columns:28px minmax(0,1fr);gap:var(--s2)}
  .items .fa{width:28px;height:28px;font-size:var(--fs-card)}
  .items.solo .item{grid-template-columns:minmax(0,1fr)}
}

/* ---------- people. In a list: a row each, with photo, name, @username and FOLLOW (a profile's Network, the
   requests, the people found on members/). Lately active: round photos side by side, @username under each (home,
   members/). ---------- */
.people{list-style:none;margin:0;padding:0;display:grid;gap:var(--s4)}
.person{display:grid;grid-template-columns:40px minmax(0,1fr) auto;gap:var(--s4);align-items:center}
.person .pa{width:40px;height:40px;border-radius:50%;border:1px solid var(--ink);background:var(--wash);overflow:hidden;display:grid;place-items:center;font:400 var(--fs-dialog) var(--mono);text-transform:uppercase;text-decoration:none;color:var(--ink)}
.person .pa img{width:100%;height:100%;object-fit:cover;display:block}
.person .pn{min-width:0;display:grid;text-decoration:none}
.person .pn b{font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.person .pn span{color:var(--grey);font-size:var(--fs-small);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.person .acts{display:flex;gap:var(--s2);align-items:center}
/* FOLLOW, FOLLOWING / UNFOLLOW, REQUESTED / CANCEL: one width, so a label never moves the button mid-press */
.btn.follow{min-width:calc(9ch + 28px)}   /* 9ch: FOLLOWING and REQUESTED, the longest */
.stackers{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:var(--s4) var(--s5)}
.stackers a{display:grid;justify-items:center;gap:var(--s2);width:72px;text-decoration:none;font-size:var(--fs-small)}
.stackers .fa{width:56px;height:56px;border-radius:50%;border:1px solid var(--ink);background:var(--wash);overflow:hidden;display:grid;place-items:center;font-size:20px;text-transform:uppercase}
.stackers .fa img{width:100%;height:100%;object-fit:cover;display:block}
.stackers span:last-child{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ---------- sheets (sign in, lists, forms over the page) and the toast ---------- */
.sheet{position:fixed;inset:0;background:rgba(0,0,0,.35);display:grid;place-items:center;z-index:30;padding:var(--s4)}
.sheetbox{background:var(--paper);border:1px solid var(--ink);border-radius:var(--radius);width:100%;max-width:380px;padding:var(--s5);position:relative;max-height:calc(100% - var(--s4));overflow:auto}
.sheetbox > div{display:grid;gap:var(--s4)}
.sheetbox h2{display:block;font-size:var(--fs-dialog);text-transform:none;letter-spacing:0;color:var(--ink);border:0;padding:0 var(--s5) 0 0;margin:0}
.sheetbox p{margin:0}
.sheetbox .row{display:flex;gap:var(--s4);align-items:center;flex-wrap:wrap}   /* a sheet's yes and Cancel */
.sheetbox p:empty{display:none}   /* the sign-in sheet's line, said only when it was opened on the way somewhere (nav.js) */
.sheetbox form{display:grid;gap:var(--s4)}
.x{position:absolute;top:var(--s2);right:var(--s4);background:none;border:0;cursor:pointer;color:var(--ink);padding:var(--s1);line-height:0}
.x svg{width:20px;height:20px;display:block}
.toast{position:fixed;left:50%;bottom:calc(env(safe-area-inset-bottom,0px) + var(--s4));transform:translateX(-50%);background:var(--ink);color:var(--paper);border-radius:var(--radius);padding:var(--s2) var(--s4);font-size:var(--fs-card);max-width:calc(100% - 2*var(--s4));z-index:40}

/* ---------- the footer: one line of small print, the same on every page: About · Privacy · hello@shelfstackd.com.
   About is the Credits on the privacy page (where the film and book data and the search come from; TMDB's logo is
   there). It sits in the column, under a hairline the width of the window, as the top bar's contents do over one. ---------- */
footer{margin-top:var(--s6);border-top:1px solid var(--hair);padding:var(--s4) max(var(--gutter), calc((100% - var(--col))/2)) var(--s5);font-size:var(--fs-small);color:var(--grey)}
footer p{margin:0}
.fnav{display:flex;flex-wrap:wrap;gap:var(--s1) var(--s2)}
.fnav a{text-decoration:none}
.fnav a:hover,.fnav a:focus-visible{color:var(--ink)}

/* ---------- a touch screen: every control takes a press anywhere in the 44 x 44px round its middle (Apple asks for
   44, Google for 48), and looks just the same: a clear ::before reaches past any edge nearer than 22px to its middle.
   A link inside a sentence is left as it is. Fields are 44px tall, in 16px type, so a phone doesn't zoom in when one
   is pressed. A page adds its own controls to this in its own <style>, with the same ::before. ---------- */
@media (pointer:coarse){
  .top a,.acct,.tabs button,.btn,.dash,h2 .more,.fnav a,.items .fa,.person .pa,.person .pn,.statlink button,.check,.linkish{position:relative}
  :is(.top a,.acct,.tabs button,.btn,.dash,h2 .more,.fnav a,.items .fa,.person .pa,.person .pn,.statlink button,.check,.linkish,.x)::before{content:"";position:absolute;top:min(0px,calc(50% - 22px));right:min(0px,calc(50% - 22px));bottom:min(0px,calc(50% - 22px));left:min(0px,calc(50% - 22px))}
  .check input{position:relative}   /* the box stays on top of its own press area */
  .items .fa,.person .pa{overflow:visible}   /* the round photo is cut by its own corners instead, so the press area isn't */
  .items .fa img,.person .pa img{position:absolute;inset:0;border-radius:50%}
  .top .add,.top .addmore{min-width:44px;justify-content:center}
  input[type=text],input[type=email],input[type=search],input[type=url],select,textarea{font-size:16px;min-height:44px}
}
/* the second row of the bar scrolls sideways inside itself, so its links' press areas need room inside it */
@media (pointer:coarse) and (max-width:820px){ .links{padding:var(--s2) 14px;margin:calc(-1 * var(--s2)) -14px 0;flex-basis:calc(100% + 28px)} }
