/* The site is drawn out of the app's own design system and nothing else.
   Every colour, radius, shadow, type step and spacing step below is copied from
   Bouky/DesignSystem/Tokens.swift rather than picked by eye, so the page and the
   app cannot drift apart. Three rules carry over with them:

     the ground is paper, and paper is pale and warm;
     surfaces sit, they do not float and they do not wobble;
     two pigments do all the pointing, sage for "this one" and clay for
     provenance and for what the reader marked themselves. */

:root {
  /* Palette.swift, light */
  --paper:        #F0EADB;
  --surface:      #FCFAF3;
  --sunken:       #E3DAC5;
  --pressed:      #D8CEB7;
  --ink:          #2A2822;
  --ink-soft:     #5C5749;
  --ink-faint:    #6B6555;
  --ink-wash:     #4A4234;   /* the one pigment every shadow is mixed from */
  --ink-line:     #B4A688;
  --hairline:     #C9BFA6;
  --clay:         #9E5232;
  --sage:         #5A7550;
  --sage-ink:     #FBFAF4;
  --sage-soft:    #DEE7D7;
  --sage-deep:    #3F5537;
  --highlighter:  #F2BC9B;
  --wood:         #C79E68;
  --wood-light:   #E0BE8C;
  --wood-dark:    #8E6A3C;
  --grain:        0.055;   /* the tooth, barely shown */

  /* Radius.swift */
  --r-chip: 10px;
  --r-field: 12px;
  --r-tile: 14px;
  --r-card: 16px;
  --r-sheet: 30px;

  /* Depth.card and Depth.tile: short, soft, and mixed from the type's own
     pigment. A cool grey shadow under warm paper is the one thing that gives a
     palette away, and a shadow that reaches the next thing is a dark band. */
  --shade-tile: 0 2px 6px rgba(74, 66, 52, 0.06);
  --shade-card: 0 4px 14px rgba(74, 66, 52, 0.08);

  /* Space.swift */
  --s-xs: 4px; --s-s: 8px; --s-m: 12px; --s-l: 16px;
  --s-xl: 20px; --s-xxl: 24px; --s-xxxl: 32px; --s-huge: 40px;

  --measure: 34rem;
  --wide: 46rem;
}

/* There is no night side to this page, and that is the app's own rule rather
   than an omission. Bouky picks its own side of the page and is paper by default
   whatever iOS is set to, because an app about reading that opens black is a
   reading app with the lamp switched off. A landing page that turned itself dark
   on a reader whose phone happened to be dark would be showing them a Bouky the
   app does not open as. `color-scheme` is declared so the scrollbar and any
   control the browser draws stay on the same side of the page as the paper. */
:root { color-scheme: light; }

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

/* The ground: the stock, and its tooth barely shown. Enough that a screenful of
   cream is not a flat swatch, never enough to read as a texture. */
body {
  margin: 0;
  min-height: 100%;
  background-color: var(--paper);
  color: var(--ink);
  font-family: "Source Sans 3", ui-sans-serif, system-ui, sans-serif;
  font-size: 15px;
  line-height: 1.62;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: var(--grain);
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23f)'/%3E%3C/svg%3E");
}

main { position: relative; z-index: 1; }

.wrap { max-width: var(--measure); margin: 0 auto; padding: var(--s-huge) var(--s-xl) 56px; }
.wrap.wide { max-width: var(--wide); }

/* Type: the seven steps, at the app's own sizes and tracking, with the reading
   face set optically larger because a Garamond's x-height is a third shorter
   than the sans's and one scale can serve both only that way. */
h1, h2, h3, .tagline, .mark, blockquote, .index-word, .spine-title {
  font-family: "EB Garamond", Georgia, serif;
}

.mark      { font-size: 40px; font-weight: 600; letter-spacing: -0.7px; line-height: 1.1; margin: 0; }
h1         { font-size: 40px; font-weight: 600; letter-spacing: -0.7px; line-height: 1.15; margin: 0 0 var(--s-xs); }
h2         { font-size: 33px; font-weight: 600; letter-spacing: -0.5px; line-height: 1.2;
             margin: 56px 0 var(--s-m); }
h3         { font-size: 24px; font-weight: 600; letter-spacing: -0.2px; margin: 0 0 var(--s-xs); }
.tagline   { font-size: 24px; line-height: 1.35; margin: var(--s-s) 0 var(--s-xl); color: var(--ink); }

p  { margin: 0 0 var(--s-l); }
ul { padding-inline-start: var(--s-xl); margin: 0 0 var(--s-l); }
li { margin-bottom: var(--s-xs); }
strong { font-weight: 600; }
.note  { font-size: 13px; color: var(--ink-faint); }
.muted { color: var(--ink-faint); }

a { color: var(--sage-deep); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--clay); }

/* A section head is ruled under the way a page is, in the faint line rather than
   in the type's own colour. */
h2 { padding-bottom: var(--s-s); border-bottom: 1px solid var(--hairline); }

/* The lockup. The corner is rounded here and nowhere else: the icon that ships
   must be square with no alpha, and no browser masks anything. */
.lockup { margin: 0 0 var(--s-xl); display: block; }
.lockup img {
  width: 88px; height: 88px; display: block;
  border-radius: 20px;
  border: 1px solid var(--hairline);
  box-shadow: var(--shade-tile);
}

/* One filled action on the page, in sage, hugging its own words. There is no big
   filled slab anywhere in the app and there is none here. */
.cta {
  display: inline-block;
  background: var(--sage);
  color: var(--sage-ink);
  padding: 10px var(--s-xl);
  border-radius: var(--r-field);
  font-weight: 600;
  font-size: 17px;
  text-decoration: none;
  box-shadow: var(--shade-tile);
}
.cta:hover { background: var(--sage-deep); color: var(--sage-ink); }
.cta-note { font-size: 13px; color: var(--ink-faint); margin-top: var(--s-m); }

/* ---- The case -----------------------------------------------------------
   The bookcase of spines was drawn, shipped and reversed. What stands on a board
   now is a cover card, every one the same size, because the work of telling one
   book from another belongs to the jacket rather than to the layout. The cards
   carry no title under them: a cover already says the title.

   A book that has never been photographed is bound and blocked instead: a
   ground, the turn of the spine along the left edge, a band at the head or the
   foot, sometimes gilt rules or a label of darker leather, and the title blocked
   large and cut short. Half the grounds are pale, which is the single thing that
   most separates a drawing of a bookcase from a photograph of one.

   Every measurement below is taken off the width of the board, the way
   ClothCover takes its own, because a cover is a drawn object rather than a
   piece of the app's type scale. */

.case { margin: var(--s-xxl) 0 var(--s-xxxl); }

.board { margin-bottom: var(--s-l); }

/* In the app the row runs out past the margin, the way a real shelf runs into
   the side of its case. On a web page it does not: a board here holds whole
   books and no book hangs off the end of it, so the page never shows a card cut
   in half by a margin the reader cannot scroll. The count is what changes with
   the width; the cards keep their proportion. */
.books {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  align-items: end;
  gap: var(--s-s);
}

/* A cover standing on a board nearly squares its corners against the books
   either side of it, and throws no shadow of its own: what keeps the row from
   floating is the soft dark where the board meets the panel. */
.cover {
  position: relative;
  width: 100%;
  aspect-ratio: 0.68;     /* the trade hardback's proportion */
  border-radius: 2px;
  overflow: hidden;
  box-shadow: inset 0 0 0 0.5px rgba(74, 66, 52, 0.30);
  font-family: "Source Sans 3", ui-sans-serif, sans-serif;
}
.cover.serif { font-family: "EB Garamond", Georgia, serif; }
.cover.condensed { font-stretch: 95%; font-weight: 800; }

/* The turn of the spine, showing along the left-hand edge. A cover is the front
   half of one sheet folded round the book, and this strip is where the rest of
   it goes. */
.cover .fold {
  position: absolute; top: 0; bottom: 0; left: 0;
  width: 5.5%;
  background: rgba(0, 0, 0, 0.14);
}
.cover .joint {
  position: absolute; top: 0; bottom: 0; left: 5.5%;
  width: 1px;
  background: rgba(0, 0, 0, 0.10);
}

/* A block of colour across the head is the commonest thing on a shelf today. */
.cover .band { position: absolute; left: 0; right: 0; height: 8.5%; }
.cover .band.head { top: 0; }
.cover .band.foot { bottom: 0; }

/* Gilt rules at head and tail: an older book, or one pretending to be. */
.cover .gilt { position: absolute; left: 9%; right: 9%; height: 1px; background: #C9A227; }

/* A label of darker leather let into the middle of the board. */
.cover .label {
  position: absolute; left: 14%; right: 9%; top: 26%; bottom: 40%;
  background: #5E2E20;
  border-radius: 1px;
}

/* The lettering. It errs large and is cut short: a title set small enough to fit
   whole is a grey mark, and what a reader wants off a shelf is the first few
   words at a size they can read from where they are. */
.cover .blocked {
  position: absolute;
  left: 15%; right: 10%;
  top: 14%;
  z-index: 1;
}
.cover.band-head .blocked { top: 20%; }
.cover.labelled .blocked { top: 29%; left: 18%; right: 12%; }
/* A binder does not break a word in the middle, so a title whose longest word
   will not stand on a line of its own comes down a step rather than being cut
   through a letter. `ClothCover` measures the word and walks the size down; here
   the few titles that need it carry the class. */
.cover.long .title { font-size: clamp(11px, 1.7vw, 13px); }

.cover .title {
  font-size: clamp(12px, 2.1vw, 16px);
  hyphens: none;
  overflow-wrap: normal;
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.2px;
  max-height: 68px;
  overflow: hidden;
  display: block;
}
.cover .author {
  display: block;
  margin-top: 6px;
  font-family: "Source Sans 3", ui-sans-serif, sans-serif;
  font-size: 7px;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  opacity: 0.85;
}

/* The plate: the painted front edge of the board, with the name the reader gave
   the shelf written on it. A shelf nobody can name is a shelf nobody can mean.
   Every paint is pale enough to carry the app's own type, which is why the name
   is never set in white. */
/* The plate is the front edge of the board, so it runs the whole width of the
   books standing on it and never less. */
.plate {
  margin-top: 6px;
  height: 26px;
  border-radius: 0 0 4px 4px;
  display: flex;
  align-items: center;
  padding: 0 var(--s-m);
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  box-shadow: var(--shade-tile);
}

/* The paints are a waxed honey, a sage, a clay, a bone: the colours a painted
   board actually comes in rather than hues off a wheel, and each pale enough to
   carry the app's own type, which is why a shelf's name is never set in white. */
.plate.honey { background: #D7AE78; }
.plate.sage  { background: #A9C1A0; }

/* ---- A kept passage ------------------------------------------------------
   Drawn the way the app draws one: the reading face, a clay rule down the side,
   the highlighter over the words that were kept, the citation underneath in the
   interface face. An illustration of the artefact, not a photograph of a
   screen. */
.kept {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-inline-start: 3px solid var(--clay);
  border-radius: var(--r-card);
  box-shadow: var(--shade-card);
  padding: var(--s-xl) var(--s-xxl) var(--s-l);
  margin: var(--s-xxl) 0;
}
.kept blockquote { margin: 0 0 var(--s-m); font-size: 21px; line-height: 1.45; }

/* The highlighter is clay thinned to a wash: the peach a marker leaves over a
   line of type, which is the single mark the whole app is built around. */
.kept mark, .wash {
  background: var(--highlighter);
  color: inherit;
  padding: 0 0.12em;
  border-radius: 2px;
}
.kept figcaption {
  font-size: 13px; color: var(--ink-faint);
  border-top: 1px solid var(--hairline);
  padding-top: var(--s-m);
}

/* ---- Rows ----------------------------------------------------------------
   A list, not a screenful of boxes. What separates one row from the next is a
   hairline, the way a notebook rules itself. */
.rows { margin: var(--s-xl) 0 0; }
.row  { padding: var(--s-l) 0; border-top: 1px solid var(--hairline); }
.row:last-child { border-bottom: 1px solid var(--hairline); }
.row p { margin: 0; color: var(--ink-soft); }

/* ---- The index -----------------------------------------------------------
   The library's own setting: kept words running on across the measure and
   wrapping, the way the index at the back of a book does, under a clay letter.
   A word is short and a row to itself wastes a screen. */
.index {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-card);
  box-shadow: var(--shade-card);
  padding: var(--s-xl) var(--s-xxl);
  margin: var(--s-xl) 0;
}
.index-letter {
  font-family: "EB Garamond", Georgia, serif;
  font-size: 20px; font-weight: 600;
  color: var(--clay);
  margin: var(--s-m) 0 var(--s-xs);
}
.index-letter:first-child { margin-top: 0; }
.index-run { font-size: 19px; line-height: 1.7; color: var(--ink); }
.index-word { font-family: "EB Garamond", Georgia, serif; }
.index-run .sep { color: var(--ink-line); padding: 0 var(--s-xs); }

/* ---- The two halves ------------------------------------------------------
   Same stock, same hairline, one simply sunken. No seam is drawn between what
   is free and what is paid, because a commercial boundary must never be
   drawable on the screen. */
.halves { display: grid; gap: var(--s-l); grid-template-columns: 1fr 1fr; margin: var(--s-xl) 0; }
.half {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-card);
  box-shadow: var(--shade-card);
  padding: var(--s-xl) var(--s-xl) var(--s-l);
}
.half.paid { background: var(--sunken); }
.half h3 { font-size: 20px; margin-bottom: var(--s-m); }
.half ul { margin-bottom: 0; padding-inline-start: var(--s-l); }
.half li { color: var(--ink-soft); }

/* A tag is sage, the way it is in the library. */
.tag {
  display: inline-block;
  background: var(--sage-soft);
  color: var(--sage-deep);
  border-radius: var(--r-chip);
  padding: 2px 10px;
  font-size: 13px;
  font-weight: 600;
  margin-inline-end: var(--s-xs);
}

/* The fifteen languages, in the order the app's own Settings screen lists them
   rather than in the alphabet's, since a reader who has seen one picker should
   recognise the other. A language names itself: a reader looking for their own
   finds it faster written in it. The one they are reading is not a link, and it
   is the only one set in the ink the page is written in. */
.langs {
  margin-top: 56px;
  padding-top: var(--s-l);
  border-top: 1px solid var(--hairline);
  font-size: 13px;
  display: flex; gap: var(--s-m) var(--s-l); flex-wrap: wrap;
  color: var(--ink-faint);
}
.langs a { color: var(--ink-faint); text-decoration: none; }
.langs a:hover { color: var(--clay); text-decoration: underline; }
.langs [aria-current="page"] { color: var(--ink); font-weight: 600; }

/* The picker and the footer stand one above the other, so only the first of the
   two carries the rule that separates them from the page. */
.langs + footer { margin-top: var(--s-xl); padding-top: 0; border-top: 0; }

footer {
  margin-top: 56px;
  padding-top: var(--s-l);
  border-top: 1px solid var(--hairline);
  font-size: 13px;
  display: flex; gap: var(--s-xl); flex-wrap: wrap;
  color: var(--ink-faint);
}
footer a { color: var(--ink-faint); }
footer a:hover { color: var(--clay); }

@media (max-width: 34rem) {
  .books { grid-template-columns: repeat(3, 1fr); }
  .halves { grid-template-columns: 1fr; }
  .mark, h1 { font-size: 34px; }
  h2 { font-size: 27px; margin-top: var(--s-huge); }
  .tagline { font-size: 21px; }
  .kept { padding: var(--s-l) var(--s-l) var(--s-m); }
  .kept blockquote { font-size: 19px; }
  .index { padding: var(--s-l); }
}
