Prettier owns formatting: .prettierrc.json, format and format:check scripts, and a one-off pass over the repo so the check is green from the start. Embedded language formatting is off deliberately - the renderers build HTML in html tagged templates and letting Prettier reflow those would change the markup customers receive. docs/ is excluded because it is hand-wrapped prose, and shell scripts have no Prettier parser. ESLint covers the JavaScript: the two browser scripts, the build and check scripts, and its own config. no-var is scoped out for the browser scripts on purpose; they are plain ES5-shaped IIFEs and a hoisting difference would only show up in a browser. ESLint cannot lint the TypeScript here: typescript@7 is the native port with no JavaScript compiler API, and typescript-eslint requires a 4.8-6.1 peer, so it refuses to install and forcing it through would leave a parser that cannot read the compiler. tsc --noEmit stays the TypeScript gate; README records the two ways to change that. lint and format:check now run in deploy.sh, and VS Code formats on save with Prettier and surfaces ESLint findings.
568 lines
11 KiB
CSS
568 lines
11 KiB
CSS
/* Hops n Grains menus, to the Atelier Dining & Hospitality system that came out
|
|
of Stitch: ivory linen and espresso for the guest's menu, burnished gold for
|
|
the one active thing on screen, Playfair Display carrying the restaurant's
|
|
voice and Plus Jakarta Sans carrying everything transactional.
|
|
See docs/design/stitch/atelier-dining-hospitality.md. */
|
|
|
|
@font-face {
|
|
font-family: 'Playfair Display';
|
|
font-style: normal;
|
|
font-weight: 400 700;
|
|
font-display: swap;
|
|
src: url('/assets/fonts/playfair-display-latin.woff2') format('woff2');
|
|
unicode-range:
|
|
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
|
|
U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
|
}
|
|
|
|
@font-face {
|
|
font-family: 'Plus Jakarta Sans';
|
|
font-style: normal;
|
|
font-weight: 200 800;
|
|
font-display: swap;
|
|
src: url('/assets/fonts/plus-jakarta-sans-latin.woff2') format('woff2');
|
|
unicode-range:
|
|
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
|
|
U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
|
}
|
|
|
|
:root {
|
|
/* guest surfaces: warm ivory linen, never stark white */
|
|
--steel: #faf8f5;
|
|
--rail: #f4f1ea;
|
|
--paper: #ffffff;
|
|
--ink: #121110;
|
|
--ink-soft: #4b4640;
|
|
--ink-dim: #8c857b;
|
|
--ink-on-paper: #121110;
|
|
--accent: #c59b58;
|
|
--copper: #b08544;
|
|
--hairline: #e6e1d8;
|
|
--hairline-soft: #efebe4;
|
|
--sheet-shadow: rgba(18, 17, 16, 0.06);
|
|
--shadow-card: 0 4px 20px -2px rgba(18, 17, 16, 0.04), 0 2px 6px -1px rgba(18, 17, 16, 0.02);
|
|
--shadow-float: 0 12px 36px -4px rgba(18, 17, 16, 0.08), 0 4px 12px -2px rgba(18, 17, 16, 0.04);
|
|
--font-display: 'Playfair Display', Georgia, 'Times New Roman', serif;
|
|
--font-ui: 'Plus Jakarta Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
|
|
--radius-card: 0.5rem;
|
|
--radius-pill: 9999px;
|
|
--step-0: 1rem;
|
|
--step-1: 1.25rem;
|
|
--step-2: 1.75rem;
|
|
--page-max: 780px;
|
|
--content-max: 46rem;
|
|
}
|
|
|
|
*,
|
|
*::before,
|
|
*::after {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
html {
|
|
-webkit-text-size-adjust: 100%;
|
|
}
|
|
|
|
body {
|
|
margin: 0;
|
|
background: var(--steel);
|
|
color: var(--ink);
|
|
font-family: var(--font-ui);
|
|
font-size: var(--step-0);
|
|
line-height: 1.5;
|
|
-webkit-font-smoothing: antialiased;
|
|
}
|
|
|
|
a {
|
|
color: inherit;
|
|
text-decoration: none;
|
|
}
|
|
|
|
:focus-visible {
|
|
outline: 2px solid var(--accent);
|
|
outline-offset: 3px;
|
|
}
|
|
|
|
/* Every uppercase label in this system is tracked, never tight. */
|
|
.label {
|
|
font-size: 0.68rem;
|
|
font-weight: 600;
|
|
letter-spacing: 0.08em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
/* ---------- Landing: the menu directory ---------- */
|
|
|
|
.landing {
|
|
max-width: var(--content-max);
|
|
margin: 0 auto;
|
|
padding: 0 1.25rem 3.5rem;
|
|
}
|
|
|
|
.masthead {
|
|
padding: clamp(2.25rem, 10vh, 4.5rem) 0 1.75rem;
|
|
border-bottom: 1px solid var(--hairline);
|
|
}
|
|
|
|
.wordmark {
|
|
margin: 0;
|
|
font-family: var(--font-display);
|
|
font-size: clamp(2rem, 8vw, 2.75rem);
|
|
font-weight: 400;
|
|
letter-spacing: -0.02em;
|
|
line-height: 1.05;
|
|
}
|
|
|
|
.masthead__tagline {
|
|
margin: 0.6rem 0 0;
|
|
color: var(--ink-soft);
|
|
font-size: 0.95rem;
|
|
}
|
|
|
|
.shelves {
|
|
display: block;
|
|
}
|
|
|
|
.shelf {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.9rem;
|
|
padding: 0.95rem 0;
|
|
border-bottom: 1px solid var(--hairline);
|
|
}
|
|
|
|
.shelf__peek {
|
|
flex: 0 0 auto;
|
|
width: 3.4rem;
|
|
height: 4.4rem;
|
|
overflow: hidden;
|
|
border: 1px solid var(--hairline);
|
|
border-radius: var(--radius-card);
|
|
background: var(--paper);
|
|
}
|
|
|
|
.shelf__peek img {
|
|
display: block;
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
object-position: top center;
|
|
transition: transform 0.4s cubic-bezier(0.2, 0.7, 0.2, 1);
|
|
}
|
|
|
|
.shelf__name {
|
|
font-family: var(--font-display);
|
|
font-size: 1.45rem;
|
|
font-weight: 400;
|
|
letter-spacing: -0.01em;
|
|
line-height: 1.15;
|
|
}
|
|
|
|
.shelf:hover .shelf__name,
|
|
.shelf:focus-visible .shelf__name {
|
|
color: var(--amber-deep, #b08544);
|
|
}
|
|
|
|
.shelf:hover .shelf__peek img,
|
|
.shelf:focus-visible .shelf__peek img {
|
|
transform: scale(1.05);
|
|
}
|
|
|
|
/* the dot leader that carries the eye from the name to the count */
|
|
.leader {
|
|
flex: 1 1 auto;
|
|
align-self: flex-end;
|
|
margin-bottom: 0.4rem;
|
|
border-bottom: 1px dotted #cdc5bd;
|
|
}
|
|
|
|
.shelf__pages {
|
|
flex: 0 0 auto;
|
|
color: var(--ink-soft);
|
|
font-size: 0.78rem;
|
|
font-weight: 600;
|
|
font-variant-numeric: tabular-nums;
|
|
letter-spacing: 0.02em;
|
|
}
|
|
|
|
.empty {
|
|
max-width: 34ch;
|
|
margin: 1.25rem 0 0;
|
|
color: var(--ink-soft);
|
|
font-size: 1.05rem;
|
|
}
|
|
|
|
/* ---------- Section page: the menu bar ---------- */
|
|
|
|
.bar {
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 20;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 1rem;
|
|
padding: 0.6rem 1.25rem;
|
|
background: color-mix(in srgb, var(--steel) 92%, transparent);
|
|
backdrop-filter: blur(8px);
|
|
border-bottom: 1px solid var(--hairline);
|
|
}
|
|
|
|
.bar__brand {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.55rem;
|
|
flex: 0 0 auto;
|
|
}
|
|
|
|
.bar__brand img {
|
|
display: block;
|
|
width: 26px;
|
|
height: 26px;
|
|
border-radius: var(--radius-pill);
|
|
}
|
|
|
|
.bar__name {
|
|
font-family: var(--font-display);
|
|
font-size: 1.05rem;
|
|
letter-spacing: -0.01em;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.bar__nav {
|
|
display: flex;
|
|
flex: 1 1 auto;
|
|
gap: 0.35rem;
|
|
overflow-x: auto;
|
|
scrollbar-width: none;
|
|
-webkit-overflow-scrolling: touch;
|
|
}
|
|
|
|
.bar__nav::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
.bar__link {
|
|
padding: 0.42rem 0.9rem;
|
|
border: 1px solid transparent;
|
|
border-radius: var(--radius-pill);
|
|
color: var(--ink-soft);
|
|
font-size: 0.78rem;
|
|
font-weight: 600;
|
|
letter-spacing: 0.02em;
|
|
white-space: nowrap;
|
|
transition:
|
|
background 0.18s ease,
|
|
color 0.18s ease;
|
|
}
|
|
|
|
.bar__link:hover {
|
|
background: color-mix(in srgb, var(--accent) 16%, transparent);
|
|
color: var(--ink);
|
|
}
|
|
|
|
.bar__link.is-current {
|
|
background: var(--ink);
|
|
color: var(--steel);
|
|
}
|
|
|
|
.pour {
|
|
position: absolute;
|
|
right: 0;
|
|
bottom: -1px;
|
|
left: 0;
|
|
height: 2px;
|
|
background: transparent;
|
|
}
|
|
|
|
.pour__fill {
|
|
display: block;
|
|
width: 0;
|
|
height: 100%;
|
|
background: var(--accent);
|
|
}
|
|
|
|
/* ---------- The pages themselves ---------- */
|
|
|
|
.section-heading {
|
|
display: flex;
|
|
align-items: baseline;
|
|
justify-content: space-between;
|
|
gap: 1rem;
|
|
max-width: var(--page-max);
|
|
margin: 1.75rem auto 1rem;
|
|
padding: 0 1.25rem;
|
|
}
|
|
|
|
.section-heading__label {
|
|
font-family: var(--font-display);
|
|
font-size: var(--step-2);
|
|
font-weight: 400;
|
|
letter-spacing: -0.015em;
|
|
}
|
|
|
|
.section-heading__date {
|
|
color: var(--ink-dim);
|
|
font-size: 0.68rem;
|
|
font-weight: 600;
|
|
letter-spacing: 0.08em;
|
|
text-transform: uppercase;
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
.notice {
|
|
max-width: var(--page-max);
|
|
margin: 0 auto 1.25rem;
|
|
padding: 0.7rem 0.9rem;
|
|
border-left: 2px solid var(--accent);
|
|
background: var(--rail);
|
|
font-size: 0.9rem;
|
|
}
|
|
|
|
.notice a {
|
|
color: var(--copper);
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.notice--admin {
|
|
max-width: none;
|
|
background: color-mix(in srgb, var(--accent) 12%, var(--rail));
|
|
}
|
|
|
|
.pages {
|
|
max-width: var(--page-max);
|
|
margin: 0 auto;
|
|
padding: 0 1.25rem 1.5rem;
|
|
}
|
|
|
|
.page {
|
|
margin: 0 0 0.85rem;
|
|
padding: 0.4rem;
|
|
background: var(--paper);
|
|
border: 1px solid var(--hairline);
|
|
border-radius: var(--radius-card);
|
|
box-shadow: var(--shadow-card);
|
|
}
|
|
|
|
.page__zoom {
|
|
display: block;
|
|
}
|
|
|
|
.page img {
|
|
display: block;
|
|
width: 100%;
|
|
height: auto;
|
|
border-radius: 0.25rem;
|
|
}
|
|
|
|
/* ---------- Footer: page index and older menus ---------- */
|
|
|
|
.foot {
|
|
max-width: var(--page-max);
|
|
margin: 0 auto 5rem;
|
|
padding: 0 1.25rem 1rem;
|
|
border-top: 1px solid var(--hairline);
|
|
}
|
|
|
|
.fold {
|
|
padding: 0.85rem 0;
|
|
border-bottom: 1px solid var(--hairline);
|
|
}
|
|
|
|
.fold summary {
|
|
color: var(--ink-soft);
|
|
font-size: 0.68rem;
|
|
font-weight: 600;
|
|
letter-spacing: 0.08em;
|
|
text-transform: uppercase;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.fold[open] summary {
|
|
color: var(--ink);
|
|
}
|
|
|
|
.index {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 0.45rem;
|
|
margin: 0;
|
|
padding: 1rem 0 0;
|
|
list-style: none;
|
|
}
|
|
|
|
.index a {
|
|
display: block;
|
|
min-width: 2.4rem;
|
|
padding: 0.35rem 0.5rem;
|
|
border: 1px solid var(--hairline);
|
|
border-radius: var(--radius-pill);
|
|
color: var(--ink-soft);
|
|
font-size: 0.78rem;
|
|
font-weight: 600;
|
|
font-variant-numeric: tabular-nums;
|
|
text-align: center;
|
|
}
|
|
|
|
.index a:hover,
|
|
.index a:focus-visible {
|
|
background: var(--ink);
|
|
color: var(--steel);
|
|
}
|
|
|
|
.older {
|
|
margin: 0.6rem 0 0;
|
|
padding: 0;
|
|
list-style: none;
|
|
}
|
|
|
|
.older a {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
gap: 1rem;
|
|
padding: 0.55rem 0.15rem;
|
|
border-bottom: 1px solid var(--hairline-soft);
|
|
}
|
|
|
|
.older__label {
|
|
font-family: var(--font-display);
|
|
font-size: 1.05rem;
|
|
}
|
|
|
|
.older__date {
|
|
color: var(--ink-dim);
|
|
font-size: 0.72rem;
|
|
font-weight: 600;
|
|
letter-spacing: 0.06em;
|
|
text-transform: uppercase;
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
.fold__back {
|
|
margin: 0.85rem 0 0;
|
|
}
|
|
|
|
.fold__back a {
|
|
color: var(--copper);
|
|
text-decoration: underline;
|
|
}
|
|
|
|
/* ---------- Counter and zoom ---------- */
|
|
|
|
.counter {
|
|
position: fixed;
|
|
right: 1.25rem;
|
|
bottom: calc(1.25rem + env(safe-area-inset-bottom));
|
|
z-index: 30;
|
|
display: inline-flex;
|
|
align-items: baseline;
|
|
gap: 0.35rem;
|
|
padding: 0.55rem 0.9rem;
|
|
border: 0;
|
|
border-radius: var(--radius-pill);
|
|
background: var(--ink);
|
|
color: var(--steel);
|
|
font: inherit;
|
|
font-size: 0.72rem;
|
|
font-weight: 600;
|
|
letter-spacing: 0.08em;
|
|
text-transform: uppercase;
|
|
font-variant-numeric: tabular-nums;
|
|
box-shadow: var(--shadow-float);
|
|
cursor: pointer;
|
|
}
|
|
|
|
.counter[hidden] {
|
|
display: none;
|
|
}
|
|
|
|
.counter__total {
|
|
color: color-mix(in srgb, var(--steel) 62%, transparent);
|
|
}
|
|
|
|
.zoom {
|
|
position: fixed;
|
|
inset: 0;
|
|
z-index: 50;
|
|
overflow: auto;
|
|
background: rgba(18, 17, 16, 0.45);
|
|
backdrop-filter: blur(8px);
|
|
-webkit-overflow-scrolling: touch;
|
|
padding: 1.25rem 0;
|
|
}
|
|
|
|
.zoom img {
|
|
display: block;
|
|
width: min(100%, 1600px);
|
|
height: auto;
|
|
margin: 0 auto;
|
|
border-radius: var(--radius-card);
|
|
box-shadow: var(--shadow-float);
|
|
}
|
|
|
|
.zoom__close {
|
|
position: fixed;
|
|
top: 0.75rem;
|
|
right: 0.75rem;
|
|
z-index: 1;
|
|
padding: 0.55rem 1rem;
|
|
border: 0;
|
|
border-radius: var(--radius-pill);
|
|
background: var(--ink);
|
|
color: var(--steel);
|
|
font: inherit;
|
|
font-size: 0.72rem;
|
|
font-weight: 600;
|
|
letter-spacing: 0.08em;
|
|
text-transform: uppercase;
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* ---------- Wider screens ---------- */
|
|
|
|
@media (min-width: 62rem) {
|
|
.landing {
|
|
padding-bottom: 4.5rem;
|
|
}
|
|
|
|
.shelf {
|
|
padding: 1.15rem 0;
|
|
}
|
|
|
|
.shelf__name {
|
|
font-size: 1.7rem;
|
|
}
|
|
|
|
.pages {
|
|
max-width: 820px;
|
|
}
|
|
}
|
|
|
|
@media print {
|
|
.bar,
|
|
.counter,
|
|
.fold,
|
|
.notice {
|
|
display: none;
|
|
}
|
|
|
|
body {
|
|
background: #fff;
|
|
}
|
|
|
|
.page {
|
|
border: 0;
|
|
box-shadow: none;
|
|
break-inside: avoid;
|
|
}
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
*,
|
|
*::before,
|
|
*::after {
|
|
animation: none !important;
|
|
transition: none !important;
|
|
scroll-behavior: auto !important;
|
|
}
|
|
}
|