/* The site's structure, the same in every look. The look (style/looks/<name>.css) sets the colours, the type and the
   shapes through the custom properties used here; a game's theme (.theme-<slug>, written by the build from its
   game.toml) sets the colours and the type again inside the game's own pages and cards. No animation runs unless the
   reader allows motion.

   Every page shares one column (.wrap): the header's edges, the footer's, and those of every block between them.
   tools/check_layout.py measures that, with the rows and columns below, at every width from a phone's to a large
   screen's. */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
/* Boxes are tinted with the paper, a shade darker. */
:root, .themed { --tint: color-mix(in srgb, var(--ink) 6%, var(--paper)); }
/* The text is 17px, and 18px on a computer's wider screen. On an iPhone or an iPad it follows the size the reader has
   chosen in the device's settings (17px unless they change it); only there, since on a Mac Safari's "body" size is
   13px, which would shrink the whole site. */
body { margin: 0; background: var(--paper); color: var(--ink); font-family: var(--font-body); font-size: 1.0625rem;
  line-height: 1.6; overflow-wrap: break-word; }
@media (min-width: 64rem) { body { font-size: 1.125rem; } }
@supports (font: -apple-system-body) and (-webkit-touch-callout: none) {
  html { font: -apple-system-body; }
  body { font-size: 1rem; }
}
a[href^="mailto:"] { overflow-wrap: anywhere; }
.themed { background: var(--paper); color: var(--ink); font-family: var(--font-body); }
/* The footer stays at the foot of the window on a short page. */
body { display: flex; flex-direction: column; min-height: 100vh; }
main { display: block; flex: 1 0 auto; padding-bottom: 3.5rem; }
img { max-width: 100%; height: auto; }
a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: .2em; }
a:hover { text-decoration-thickness: 2px; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
h1, h2, h3 { font-family: var(--font-display); font-weight: var(--display-weight); line-height: 1.15;
  color: var(--heading, var(--ink)); text-wrap: balance; }
h1 { font-size: clamp(2rem, 6vw, 2.75rem); margin: 0 0 .5rem; }
h2 { font-size: clamp(1.45rem, 3.6vw, 1.8rem); margin: 2.25rem 0 .75rem; color: var(--subheading, var(--heading, var(--ink))); }
h3 { font-size: 1.2rem; margin: 1.5rem 0 .35rem; }
p { margin: 0 0 1rem; }
/* Lines broken for an even edge where lines are long; on a phone, Safari would leave them visibly short. */
@media (min-width: 48rem) { p { text-wrap: pretty; } }
ul { margin: 0 0 1rem; padding-left: 1.25rem; }

.skip { position: absolute; left: 1rem; top: -5rem; z-index: 10; padding: .6rem 1rem; background: var(--ink);
  color: var(--paper); border-radius: var(--radius-small); }
.skip:focus { top: 1rem; }
.wrap { width: 100%; max-width: 70rem; margin: 0 auto; padding: 0 1rem; }
@media (min-width: 48rem) { .wrap { padding: 0 2rem; } }
/* Running text: lines of about 75 characters at most. */
.prose > *, .lead { max-width: 38rem; }
.prose li, .feature li { margin: .3rem 0; }

/* The header: the studio's name, and its two links. The links' text ends at the column's edge; their padding, which
   a finger hits too, reaches past it. */
.site-header { background: var(--header-bg, var(--paper)); border-bottom: 1px solid var(--line); }
.header-wrap { display: flex; align-items: center; justify-content: space-between; gap: .25rem 1rem;
  flex-wrap: wrap; padding-top: .5rem; padding-bottom: .5rem; }
.wordmark { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0 .55rem; max-width: 100%; padding: .35rem 0;
  color: var(--header-ink, var(--ink));
  font-family: var(--font-display); font-weight: var(--display-weight); line-height: 1; text-decoration: none;
  font-size: calc(var(--wordmark-size, 1.4rem) * var(--wordmark-scale, 1)); }
.mark { display: block; width: calc(var(--mark-width, 2.6rem) * var(--wordmark-scale, 1)); height: auto; flex: none; }
.wordmark-rest { color: var(--wordmark-rest, inherit); }
.site-nav { display: flex; gap: .25rem; margin-inline: -.75rem; }
.site-nav a { display: block; padding: .7rem .75rem; border-radius: var(--radius-small); color: var(--header-ink, var(--ink));
  font-weight: 600; text-decoration: none; }
.site-nav a:hover { background: var(--header-hover, var(--tint)); }
.site-nav a[aria-current="page"] { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: .45em; }
/* On a phone, the name and the two links share one line, with a smaller name on the narrowest; below 340 points or
   so, the links go under the name, their text in line with it. */
@media (max-width: 30rem) {
  :root { --wordmark-scale: .82; }
  .wordmark { gap: .4rem; }
  .site-nav { margin-inline: -.45rem; }
  .site-nav a { padding: .7rem .45rem; }
}
@media (max-width: 22.5rem) {
  :root { --wordmark-scale: .72; }
  .site-nav { gap: 0; margin-inline: -.4rem; }
  .site-nav a { padding: .7rem .4rem; font-size: .95rem; }
}

/* The home page's opening, and the heads of the other pages. */
.hero { background: var(--hero-bg, transparent); padding: clamp(2rem, 7vw, 4.5rem) 0 clamp(1.5rem, 5vw, 3rem); }
.hero h1 { font-size: clamp(2.4rem, 8vw, 4rem); margin-bottom: .75rem; }
.tagline { max-width: 44rem; margin: 0; color: var(--muted); font-size: clamp(1.2rem, 3.4vw, 1.6rem); line-height: 1.35;
  text-wrap: balance; }
.page-head { padding-top: clamp(1.5rem, 5vw, 3rem); padding-bottom: .5rem; }
.section { padding: .5rem 0 1rem; }
.lead { font-size: 1.25rem; line-height: 1.5; }
.meta, .date { color: var(--muted); font-size: .95rem; }
.more { margin: 1rem 0 0; font-weight: 600; }
.more a { display: inline-block; padding: .6rem 0; }

/* The games' cards on the home page: each in its game's own colours, the whole card a link. */
.cards { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.25rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr)); }
.card { position: relative; display: flex; flex-direction: column; overflow: hidden; border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow); }
.card img, .card .placeholder { display: block; width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; }
/* A portrait picture (a phone's screenshot) is shown whole in the frame, on the game's tint, never cropped. */
.card img.portrait { object-fit: contain; background: var(--tint); }
.placeholder { background: linear-gradient(135deg, var(--tint), color-mix(in srgb, var(--accent) 40%, var(--paper))); }
.card-body { display: flex; flex: 1; flex-direction: column; padding: 1rem 1.15rem 1.1rem; }
.card-title { margin: 0 0 .4rem; color: var(--ink); font-size: 1.4rem; }
.card-title a { color: var(--ink); text-decoration: none; }
.card-title a::after { content: ""; position: absolute; inset: 0; }
.card:focus-within { outline: 3px solid var(--focus); outline-offset: 3px; }
.card p { margin-bottom: .6rem; }
.card .meta { margin: auto 0 0; }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .card { transition: transform .15s ease, box-shadow .15s ease; }
  .card:hover { transform: translateY(-3px); }
}
/* The newest game, featured: the width of the grid, and on a wide screen its picture beside its text. */
.card.featured { grid-column: 1 / -1; }
@media (min-width: 48rem) {
  .card.featured { flex-direction: row; }
  .card.featured > picture { flex: 0 0 56%; }
  .card.featured .card-body { justify-content: center; padding: 2rem 2.25rem; }
  .card.featured .card-title { font-size: clamp(1.6rem, 2.6vw, 2.2rem); }
  .card.featured p { font-size: 1.15rem; }
  .card.featured .meta { margin-top: .5rem; font-size: 1rem; }
}

/* The promises: in a row from an upright iPad's width up. */
.promise-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr)); }
.promise-list li { padding: 1.1rem 1.2rem; background: var(--tint); border-radius: var(--radius); }
.promise-title { display: block; margin-bottom: .3rem; color: var(--heading, var(--ink)); font-family: var(--font-display);
  font-weight: var(--display-weight); font-size: 1.2rem; }

/* The catalogue: one line for each game, its icon beside it. */
.catalogue { list-style: none; margin: 1rem 0 0; padding: 0; display: grid; gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 27rem), 1fr)); }
.entry { position: relative; display: flex; flex-wrap: wrap; gap: 1rem; align-items: flex-start; padding: 1rem 1.15rem;
  border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); }
.entry > picture, .entry > .placeholder { flex: none; }
/* The text, as tall as the entry: its last line (ages, devices, availability) at the foot, in line across a row. */
.entry > div { display: flex; flex: 1 1 14rem; flex-direction: column; align-self: stretch; min-width: 0; }
.entry .meta { margin-top: auto; }
.entry h2 { margin: 0 0 .3rem; color: var(--ink); font-size: 1.4rem; }
.entry h2 a { color: var(--ink); text-decoration: none; }
.entry h2 a::after { content: ""; position: absolute; inset: 0; }
.entry:focus-within { outline: 3px solid var(--focus); outline-offset: 3px; }
.entry p { margin: 0 0 .4rem; }
.app-icon { display: block; width: 4.5rem; height: 4.5rem; aspect-ratio: 1; object-fit: cover; border-radius: 22.5%;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .2), 0 2px 8px rgba(0, 0, 0, .12); }

/* A game's pages: its name and icon, then the links between its pages. */
.game-top { padding: clamp(1.5rem, 5vw, 2.75rem) 0 1.5rem; }
.game-head { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; margin-bottom: 1rem; }
.game-head > picture { flex: none; }
.game-head > div { flex: 1 1 14rem; min-width: 0; }
/* A game's name beside its icon: a little smaller than other pages' headings, for long names to take two lines. */
.game-head h1 { margin: 0; font-size: clamp(1.75rem, 5.5vw, 2.5rem); }
.subtitle { margin: .3rem 0 0; color: var(--muted); font-size: 1.15rem; }
/* Where the game can be had: a line for each store, its words beside the label (wrapping beside it, or under it
   when the label leaves them too little room). */
.availability { margin: 0 0 1rem; padding: 0; list-style: none; }
.availability li { display: flex; flex-wrap: wrap; align-items: baseline; gap: .25rem .5rem; }
.availability li + li { margin-top: .5rem; }
.availability li > span:last-child { flex: 1 1 8rem; }
.status { display: inline-block; padding: .25rem .85rem; border-radius: 999px; background: var(--accent);
  color: var(--accent-ink); font-weight: 700; font-size: .95rem; text-decoration: none; }
.game-nav { display: flex; flex-wrap: wrap; gap: 0 1.5rem; margin-top: 1.25rem; border-bottom: 1px solid var(--line); }
.game-nav a { margin-bottom: -1px; padding: .75rem 0; border-bottom: 3px solid transparent; font-weight: 600;
  text-decoration: none; }
.game-nav a[aria-current="page"] { color: var(--ink); border-bottom-color: var(--accent); }
.game-top-picture { margin: 1.75rem 0 0; }
.game-top-picture img { display: block; width: 100%; height: auto; border-radius: var(--radius-small);
  box-shadow: 0 2px 6px rgba(0, 0, 0, .14), 0 12px 32px rgba(0, 0, 0, .12); }
/* A portrait main picture (a phone's screenshot) is shown whole: 70% of the window's height (pages.py's
   hero_sizes says the same). */
.game-top-picture img.portrait { width: auto; max-height: 70vh; margin-inline: auto; }
/* On a computer's screen, the main picture beside the game's name (a portrait one in a narrower column, at most
   40rem tall). */
@media (min-width: 64rem) {
  .game-top-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); gap: 3rem; align-items: center; }
  .game-top-grid:has(img.portrait) { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); }
  .game-top-picture img.portrait { max-height: min(70vh, 40rem); }
  .game-top-picture { margin: 0; }
}
/* The description's sections: two abreast on a tablet or a computer. Each spans two of the grid's rows, its heading
   in the first and its text in the second, so that in each row the headings' last lines are on one line and the
   texts start on one line, however many lines each heading takes. */
@media (min-width: 48rem) {
  .features { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 3rem; }
  .feature { display: grid; grid-row: span 2; grid-template-rows: subgrid; }
  .feature > h2 { align-self: end; }
}

/* The pictures from a game, side by side: swiped on a phone or a tablet, scrolled sideways on a computer; the next
   one shows at the edge. Until the column is at its widest, the row runs to the window's edges; beyond, it stops at
   the column's, as everything else does (and the pictures' shadows fall straight down, so the edge cuts none). A
   swipe comes to rest on a picture when near one ("proximity": "mandatory" made WebKit jump to the end of a short
   row when the page's height changed). Portrait pictures (a phone's screenshots) are narrower. */
.gallery { list-style: none; display: flex; gap: 1rem; margin: 0 -1rem; padding: .25rem 1rem .75rem; overflow-x: auto;
  overscroll-behavior-x: contain; scroll-snap-type: x proximity; scroll-padding-inline: 1rem; }
.gallery li { flex: 0 0 min(85%, 34rem); scroll-snap-align: start; }
.gallery li:has(img.portrait) { flex-basis: min(60%, 15rem); }
.gallery figure { margin: 0; }
.gallery img { display: block; width: 100%; height: auto; border-radius: var(--radius-small);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .08), 0 4px 6px -3px rgba(0, 0, 0, .25); }
.gallery figcaption { margin-top: .5rem; color: var(--muted); font-size: .95rem; }
@media (min-width: 48rem) { .gallery { margin: 0 -2rem; padding-inline: 2rem; scroll-padding-inline: 2rem; } }
@media (min-width: 64rem) { .gallery li { flex-basis: calc((100% - 2rem) / 3.25); } }
@media (min-width: 70rem) { .gallery { margin-inline: 0; padding-inline: 0; scroll-padding-inline: 0; } }

/* At a glance: the facts parents check, in the same place for every game. In a narrow column each label is over its
   value; with room, beside it, the values one under another; with more room, two facts a row, the halves' rows on
   one line (the two long notes, read aloud and Game Center, share the last). */
.glance { container-type: inline-size; }
.glance dl { margin: 0; padding: .35rem 1.25rem; background: var(--tint); border-radius: var(--radius); }
.glance dl > div { padding: .75rem 0; border-top: 1px solid var(--line); }
.glance dl > div:first-child { border-top: 0; }
.glance dt { color: var(--heading, var(--ink)); font-weight: 700; }
.glance dd { margin: 0; }
@container (min-width: 30rem) {
  .glance dl { display: grid; grid-template-columns: max-content minmax(0, 1fr); column-gap: 1.5rem; }
  .glance dl > div { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; }
}
@container (min-width: 62rem) {
  .glance dl { grid-template-columns: max-content minmax(0, 1fr) 1rem max-content minmax(0, 1fr); column-gap: 1.25rem;
    padding-inline: 1.5rem; }
  .glance dl > div:nth-child(odd) { grid-column: 1 / 3; }
  .glance dl > div:nth-child(even) { grid-column: 4 / 6; }
  .glance dl > div:nth-child(2) { border-top: 0; }
}

/* The foot of every page: its links are targets a finger can hit, 44 points tall. */
.site-footer { padding: 1.75rem 0 2rem; background: var(--footer-bg, transparent); border-top: 1px solid var(--line);
  color: var(--muted); font-size: .95rem; }
.site-footer p { margin: 0; }
.site-footer a { color: inherit; }
.site-footer .footer-promises { margin-bottom: .25rem; color: var(--ink); font-weight: 700; }
.footer-links { display: flex; flex-wrap: wrap; gap: 0 1.5rem; margin: 0; padding: 0; list-style: none; }
.footer-links a, .footer-contact a { display: inline-block; padding: .65rem 0; }

/* The studio's look, "Chart": chosen by the user on 2026-10-26 from five, a mix of their A and B, "softer than B but
   more historical looking than A". Parchment paper, sepia ink, a sea teal and a map red; serif headings (New York on
   Apple devices) over the system's own type for the text; a dotted route under the studio's name, as on an old chart;
   gently rounded corners. */
:root {
  --paper: #fcf7ec;
  --ink: #2b2620;
  --muted: #5e574d;
  --accent: #22625c;
  --accent-ink: #ffffff;
  --line: #e7dac3;
  --focus: #b4532a;
  --heading: #2b2620;
  --subheading: #22625c;
  --wordmark-rest: #a94c25;
  --font-body: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-display: ui-serif, "New York", "Iowan Old Style", Georgia, serif;
  --display-weight: 600;
  --wordmark-size: 1.45rem;
  --radius: 14px;
  --radius-small: 9px;
  --shadow: 0 1px 2px rgba(43, 38, 32, .06), 0 6px 18px rgba(43, 38, 32, .07);
  --hero-bg: linear-gradient(180deg, #f5ead4 0%, #fcf7ec 100%);
  --tint: #f5ecda;
}
.wordmark { letter-spacing: .01em; }
.hero h1::after { content: ""; display: block; width: 7.5rem; height: 6px; margin-top: 1rem;
  background: radial-gradient(circle, #a94c25 2px, transparent 2.5px) 0 50% / 12px 6px repeat-x; }
.tagline { font-family: var(--font-display); font-style: italic; }
.promise-list li { border: 1px solid var(--line); }

/* Each game's theme, from its game.toml */
.theme-the-spice-trail { --paper: #fbf3dd; --ink: #2b2118; --muted: #6b5a48; --accent: #2c6a8a; --accent-ink: #fbf3dd; --line: #e2d6bb; --heading: #2b2118; --subheading: #2c6a8a; --font-body: Palatino, "Palatino Linotype", "Book Antiqua", Georgia, serif; --font-display: Palatino, "Palatino Linotype", "Book Antiqua", Georgia, serif; --display-weight: 700; }
