/* Grotesque Contest results page (/contests/grotesque-2026). Values come from
   the Paper mock; the page is 1440 wide there, with 120px gutters. Ported from
   the .xyz bundle (fortfoundry repo, src/campaigns/contests/grotesque-2026/).

   Only this page links this file, and every rule is scoped under .grotesque,
   so nothing here reaches the site's nav, footer or popups, and the keyframes
   carry the page's name so they can't collide with the site's. */

.grotesque {
  --ink: #0C0A08;
  --bone: #E4E0BB;
  --bone-dim: #C9C4A6;
  --red: #ED3132;
  --red-dark: #B21E20;
  --rule: #3A352C;
  --gutter: 120px;
  --tear-w: 1200px;
  --tear-h: 64px;
  /* Room below the red sheet for its torn edge: .content clips anything that
     hangs past it, so the edge has to land on this page's own black. */
  padding-bottom: 96px;
  background: var(--ink);
  color: var(--bone);
  font-family: var(--font-family-sans);
}
/* ---------- Site footer, in the contest's colours ---------- */
/* The layout's own footer (layout.html), reskinned for this page only: it is
   the footer that follows a .content holding .grotesque, and this file loads
   nowhere else. Same layout and links; ink, bone and red instead of the
   site's grey, white and blue. The page runs straight into it, no gap. */
.content:has(.grotesque) + .footer {
  --ink: #0C0A08;
  --bone: #E4E0BB;
  --bone-faint: #B9B498;
  --red: #ED3132;
  margin-top: 0;
  background-color: var(--ink);
}
.content:has(.grotesque) + .footer .footer__tagline > div { color: var(--bone); }
.content:has(.grotesque) + .footer .footer__tagline-accent { color: var(--red); }
.content:has(.grotesque) + .footer section h2 { color: var(--bone-faint); }
.content:has(.grotesque) + .footer li a,
.content:has(.grotesque) + .footer .footer__newsletter h3,
.content:has(.grotesque) + .footer .footer__newsletter-input,
.content:has(.grotesque) + .footer .footer__newsletter-submit,
.content:has(.grotesque) + .footer .footer__newsletter-success { color: var(--bone); }
.content:has(.grotesque) + .footer li a:hover,
.content:has(.grotesque) + .footer .footer__newsletter-submit:hover { color: var(--red); }
.content:has(.grotesque) + .footer .footer__newsletter-field { border-bottom-color: rgb(228 224 187 / .35); }
.content:has(.grotesque) + .footer .footer__newsletter-input::placeholder { color: rgb(228 224 187 / .55); }
.content:has(.grotesque) + .footer .footer__copyright { color: var(--bone-faint); }
/* The site's icons are white SVG backgrounds; used as masks over a fill
   instead, the same files wear the page's red, turning bone on hover. */
.content:has(.grotesque) + .footer .footer__social a {
  background-color: var(--red);
  -webkit-mask: var(--icon) center / contain no-repeat;
  mask: var(--icon) center / contain no-repeat;
}
.content:has(.grotesque) + .footer .footer__social a:hover,
.content:has(.grotesque) + .footer .footer__social a:focus-visible { background-color: var(--bone); }
.content:has(.grotesque) + .footer a.social-icon-instagram { --icon: url("/static/images/instagram.svg"); background-image: none; }
.content:has(.grotesque) + .footer a.social-icon-x { --icon: url("/static/images/x.svg"); background-image: none; }
.content:has(.grotesque) + .footer a.social-icon-dribbble { --icon: url("/static/images/dribbble.svg"); background-image: none; }
html:has(.grotesque) { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html:has(.grotesque) { scroll-behavior: auto; } }

.grotesque img { display: block; max-width: 100%; }
.grotesque a { color: inherit; }
.grotesque h1, .grotesque h2, .grotesque p, .grotesque ul, .grotesque ol { margin: 0; }
.grotesque ul, .grotesque ol { padding: 0; list-style: none; }
.grotesque :focus-visible { outline: 2px solid var(--red); outline-offset: 3px; }
/* styles.css sets every `.content section h2` as a 12px uppercase label with a
   rule under it. Undo the parts this page's headings don't set themselves. */
.content .grotesque section h2 { margin: 0; padding: 0; border: 0; text-align: inherit; text-transform: none; }

/* ---------- Shared type ---------- */
.grotesque .kicker {
  font-family: "Termina", system-ui, sans-serif; font-weight: 600;
  font-size: 12px; line-height: 16px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--red);
}
.grotesque .kicker--dark { color: var(--red-dark); }
.grotesque .section-title {
  font-family: "Silverberg", system-ui, sans-serif; font-weight: 700;
  font-size: 80px; line-height: 80px; letter-spacing: -0.02em; color: var(--bone);
}
.grotesque .section-title--small { font-size: 64px; line-height: 64px; }
.grotesque .section-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 48px; }
.grotesque .section-head > div { display: flex; flex-direction: column; gap: 12px; }
.grotesque .section-head--ruled { padding-bottom: 24px; border-bottom: 1px solid var(--rule); }

/* ---------- Hero ---------- */
/* The house fills the right of the band and dissolves into the page in grain,
   so the copy sits on the same black the picture melts into. Two masks: the
   box's left edge is a slant (img/house-fade-edge.svg) that keeps only the
   copy dark, sized in pixels from the gutter because the copy is; the picture
   inside it fades at the foot (img/house-fade.svg). --art-ratio is house.jpg's
   shape: change it with the image. */
.grotesque .hero {
  --art-ratio: 1080 / 800;
  --art-edge: calc(var(--gutter) + 1080px);
  position: relative; isolation: isolate; display: flex; align-items: center;
  min-height: clamp(640px, calc(100svh - var(--nav-height-desktop)), 820px); overflow: clip;
}
.grotesque .hero__art {
  position: absolute; z-index: -1; inset: 0;
  -webkit-mask:
    url("img/house-fade-edge.svg") 0 0 / var(--art-edge) 100% no-repeat,
    linear-gradient(#000, #000) var(--art-edge) 0 / 100% 100% no-repeat;
  mask:
    url("img/house-fade-edge.svg") 0 0 / var(--art-edge) 100% no-repeat,
    linear-gradient(#000, #000) var(--art-edge) 0 / 100% 100% no-repeat;
}
/* The house with every window dark, then one layer per window's light, all
   sized and masked the same way so they register exactly. Each layer is the
   full picture's size and transparent outside its window. */
.grotesque .hero__art::before, .grotesque .hero__light {
  content: ""; position: absolute; top: 0; right: 0; bottom: 0; width: 72%;
  background: url("img/house-dark.jpg") center top / cover no-repeat;
  -webkit-mask: url("img/house-fade.svg") 0 0 / 100% 100% no-repeat;
  mask: url("img/house-fade.svg") 0 0 / 100% 100% no-repeat;
}

/* The lights. Mostly on, cutting out like a bad bulb now and then, and the
   odd room going dark for a few seconds. Durations don't share factors, so
   the windows never fall into step. Steps make every change a hard cut. */
.grotesque .hero__light { animation: var(--flicker) var(--length) steps(1, end) var(--start) infinite; }
.grotesque .hero__light--clock  { background-image: url("img/window-clock.webp");  --flicker: grotesque-bulb;  --length: 9.7s;  --start: -2s; }
.grotesque .hero__light--slits  { background-image: url("img/window-slits.webp");  --flicker: grotesque-blink; --length: 6.1s;  --start: -4s; }
.grotesque .hero__light--trio-l { background-image: url("img/window-trio-l.webp"); --flicker: grotesque-blink; --length: 13.3s; --start: -7s; }
.grotesque .hero__light--trio-m { background-image: url("img/window-trio-m.webp"); --flicker: grotesque-room;  --length: 19s;   --start: -5s; }
.grotesque .hero__light--trio-r { background-image: url("img/window-trio-r.webp"); --flicker: grotesque-bulb;  --length: 11.9s; --start: -1s; }
.grotesque .hero__light--mid-l  { background-image: url("img/window-mid-l.webp");  --flicker: grotesque-room;  --length: 23s;   --start: -15s; }
.grotesque .hero__light--mid-r  { background-image: url("img/window-mid-r.webp");  --flicker: grotesque-bulb;  --length: 8.3s;  --start: -6s; }
.grotesque .hero__light--low-l  { background-image: url("img/window-low-l.webp");  --flicker: grotesque-blink; --length: 10.9s; --start: -3s; }
.grotesque .hero__light--low-r  { background-image: url("img/window-low-r.webp");  --flicker: grotesque-room;  --length: 17.3s; --start: -11s; }
.grotesque .hero__light--low-c  { background-image: url("img/window-low-c.webp");  --flicker: grotesque-bulb;  --length: 14.1s; --start: -9s; }
@keyframes grotesque-bulb {
  0%, 86% { opacity: 1; }
  87% { opacity: .15; } 88% { opacity: 1; } 90% { opacity: .1; }
  91% { opacity: .9; } 93% { opacity: .25; } 94%, 100% { opacity: 1; }
}
@keyframes grotesque-blink {
  0%, 40% { opacity: 1; }
  41% { opacity: .05; } 42% { opacity: 1; } 43% { opacity: .05; } 45%, 100% { opacity: 1; }
}
@keyframes grotesque-room {
  0%, 55% { opacity: 1; }
  56% { opacity: .2; } 57% { opacity: 1; } 58%, 78% { opacity: 0; }
  79% { opacity: .6; } 80% { opacity: .1; } 82%, 100% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .grotesque .hero__light { animation: none; } }
.grotesque .hero__copy {
  display: flex; flex-direction: column; align-items: flex-start;
  width: min(100%, 680px); padding: 64px 48px 96px var(--gutter);
  text-shadow: 0 2px 32px rgb(12 10 8 / .7);
}
.grotesque .hero__title {
  max-width: 520px; padding-top: 16px;
  font-family: "Silverberg", system-ui, sans-serif; font-weight: 700;
  font-size: 112px; line-height: 100px; letter-spacing: -0.02em; color: var(--bone);
}
.grotesque .hero__copy > .kicker { font-size: 14px; line-height: 20px; }
.grotesque .hero__tagline {
  padding-top: 28px; color: var(--red);
  font-family: "Silverberg", system-ui, sans-serif; font-weight: 700;
  font-size: 40px; line-height: 48px; letter-spacing: -0.01em;
}
.grotesque .hero__dates { padding-top: 32px; font-weight: 600; font-size: 20px; line-height: 28px; }
.grotesque .hero__cta { margin-top: 40px; text-shadow: none; }

.grotesque .button {
  display: inline-flex; align-items: center; height: 56px; padding-inline: 32px;
  border-radius: 999px; background: var(--bone); color: var(--ink); text-decoration: none;
  font-weight: 700; font-size: 18px; line-height: 24px; white-space: nowrap;
}
.grotesque .button:hover { background: #F2EFD3; }

/* ---------- Winners ---------- */
.grotesque .winners { display: flex; flex-direction: column; gap: 56px; padding: 112px var(--gutter); }
.grotesque .winners__intro { flex: 0 0 440px; color: var(--bone-dim); font-size: 17px; line-height: 26px; }
.grotesque .winners__body { display: flex; align-items: flex-start; gap: 64px; }

.grotesque .first {
  display: flex; align-items: flex-end; gap: 40px; flex: 0 1 744px;
  padding: 32px; border-radius: 24px; background: var(--red); color: var(--ink);
}
.grotesque .first__cover { flex: 0 0 352px; }
.grotesque .first__cover img { width: 352px; height: 440px; object-fit: cover; border-radius: 12px; }
.grotesque .first__copy { display: flex; flex-direction: column; gap: 14px; padding-bottom: 8px; min-width: 0; }
.grotesque .first__label {
  font-family: "Termina", system-ui, sans-serif; font-weight: 600;
  font-size: 12px; line-height: 16px; letter-spacing: 0.18em; text-transform: uppercase;
}
.grotesque .first__handle {
  font-family: "Silverberg", system-ui, sans-serif; font-weight: 700;
  font-size: 34px; line-height: 38px; letter-spacing: -0.01em; overflow-wrap: anywhere;
  color: var(--bone);
}
.grotesque .first__handle a { text-decoration: none; }
.grotesque .first__handle a:hover { text-decoration: underline; }
.grotesque .first__fonts { font-weight: 500; font-size: 16px; line-height: 25px; }
/* Each font name links to its page on the site. */
.grotesque .first__fonts a, .grotesque .place__fonts a { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.grotesque .first__fonts a:hover, .grotesque .place__fonts a:hover { color: var(--bone); }
.grotesque .first__prize { font-weight: 700; font-size: 15px; line-height: 20px; }

.grotesque .places { display: flex; flex-direction: column; flex: 0 0 392px; }
.grotesque .place { display: flex; align-items: center; gap: 20px; padding-block: 13px; border-bottom: 1px solid var(--rule); }
.grotesque .place:first-child { padding-top: 0; }
.grotesque .place:last-child { border-bottom: 0; padding-bottom: 0; }
.grotesque .place img { width: 80px; height: 100px; object-fit: cover; border-radius: 6px; flex-shrink: 0; }
.grotesque .place__copy { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.grotesque .place__label {
  color: var(--red);
  font-family: "Termina", system-ui, sans-serif; font-weight: 600;
  font-size: 11px; line-height: 16px; letter-spacing: 0.16em; text-transform: uppercase;
}
.grotesque .place__handle {
  font-family: "Silverberg", system-ui, sans-serif; font-weight: 700;
  font-size: 24px; line-height: 28px; overflow-wrap: anywhere;
}
.grotesque .place__handle a { text-decoration: none; }
.grotesque .place__handle a:hover { text-decoration: underline; }
.grotesque .place__fonts { color: var(--bone-dim); font-size: 14px; line-height: 20px; }

/* ---------- Paper ---------- */
/* The bone brief and the red app pitch are sheets of paper: grain over their
   colour, and a torn edge top and bottom that hangs over the black. The tears
   are tiles (img/tear-*.svg, with the same grain baked in), repeated across
   at a fixed size so the rip keeps its scale at any width. */
.grotesque .paper { position: relative; z-index: 1; background: url("img/grain.svg") 0 0 / 240px 240px, var(--paper); }
.grotesque .paper::before, .grotesque .paper::after {
  content: ""; position: absolute; left: 0; right: 0; height: var(--tear-h); pointer-events: none;
  background-repeat: repeat-x; background-size: var(--tear-w) var(--tear-h);
}
/* One pixel of overlap so no hairline of black shows at the seam. */
.grotesque .paper::before { bottom: calc(100% - 1px); background-image: var(--tear-top); }
.grotesque .paper::after { top: calc(100% - 1px); background-image: var(--tear-bottom); }

/* ---------- Brief + prizes ---------- */
.grotesque .brief {
  --paper: var(--bone);
  --tear-top: url("img/tear-bone-top.svg"); --tear-bottom: url("img/tear-bone-bottom.svg");
  display: flex; align-items: flex-start; justify-content: space-between; gap: 96px; padding: 96px var(--gutter);
}
.grotesque .brief__copy { display: flex; flex-direction: column; gap: 20px; flex: 0 1 640px; }
.grotesque .brief__title {
  color: var(--ink);
  font-family: "Silverberg", system-ui, sans-serif; font-weight: 700;
  font-size: 48px; line-height: 52px; letter-spacing: -0.01em;
}
.grotesque .brief__body { max-width: 560px; color: #2A2620; font-size: 18px; line-height: 29px; }
.grotesque .prizes { display: flex; flex-direction: column; gap: 20px; flex: 0 0 464px; padding: 32px; border-radius: 20px; background: var(--ink); }
.grotesque .prizes__title { font-family: "Silverberg", system-ui, sans-serif; font-weight: 700; font-size: 32px; line-height: 36px; letter-spacing: 0; }
.grotesque .prizes__list { display: flex; flex-direction: column; margin: 4px 0 0; border-top: 1px solid var(--rule); }
.grotesque .prizes__row { display: flex; flex-direction: column; gap: 4px; padding-block: 14px; border-bottom: 1px solid var(--rule); }
.grotesque .prizes__row:last-child { padding-bottom: 0; border-bottom: 0; }
.grotesque .prizes__row dt {
  color: var(--red);
  font-family: "Termina", system-ui, sans-serif; font-weight: 600;
  font-size: 11px; line-height: 16px; letter-spacing: 0.16em; text-transform: uppercase;
}
.grotesque .prizes__row dd { margin: 0; color: var(--bone); font-size: 16px; line-height: 24px; }

/* ---------- App ---------- */
/* Red paper: the pitch on the left, the app screenshot on the right, set at a
   slight tilt like a print laid on the sheet. */
.grotesque .app {
  --paper: var(--red);
  --tear-top: url("img/tear-red-top.svg"); --tear-bottom: url("img/tear-red-bottom.svg");
  display: grid; grid-template-columns: minmax(0, 520px) minmax(0, 1fr); align-items: center; gap: 72px;
  padding: 104px var(--gutter) 112px; color: var(--ink);
}
.grotesque .kicker--bone { color: var(--bone); }
.grotesque .app__copy { display: flex; flex-direction: column; align-items: flex-start; gap: 20px; }
.grotesque .app__pitch { display: flex; flex-direction: column; gap: 20px; }
.grotesque .app__title {
  font-family: "Silverberg", system-ui, sans-serif; font-weight: 700;
  font-size: 64px; line-height: 62px; letter-spacing: -0.02em; color: var(--ink);
}
/* A rough marker swipe under one word (img/marker-underline.svg). It's a
   mask, so it inks in the headline's own color, and it sits high enough to
   clear the cap tops of the next line, which runs tighter than the font size. */
.grotesque .marked { position: relative; white-space: nowrap; }
.grotesque .marked::after {
  content: ""; position: absolute; left: -0.06em; right: -0.1em; bottom: 0.02em; height: 0.17em;
  background: currentColor;
  -webkit-mask: url("img/marker-underline.svg") 0 0 / 100% 100% no-repeat;
  mask: url("img/marker-underline.svg") 0 0 / 100% 100% no-repeat;
  pointer-events: none;
}
.grotesque .app__body { max-width: 460px; color: #2A0B0B; font-size: 18px; line-height: 28px; }
.grotesque .app__actions { display: flex; flex-wrap: wrap; gap: 12px; padding-top: 12px; }
/* One an <a>, one a <button>: the resets make them a matched pair, and the
   outline one gives back its border width in padding so they share a height. */
.grotesque .app__button {
  display: inline-flex; align-items: center; justify-content: center; height: 56px; padding-inline: 30px;
  border: 0; border-radius: 999px; background: var(--ink); color: var(--bone); cursor: pointer;
  font-family: var(--font-family-sans); font-weight: 700; font-size: 18px; line-height: 24px;
  text-decoration: none; white-space: nowrap; transition: background-color 150ms ease, color 150ms ease;
}
.grotesque .app__button:hover { background: #2B2620; }
.grotesque .app__button--alt { border: 2px solid var(--ink); padding-inline: 28px; background: transparent; color: var(--ink); }
.grotesque .app__button--alt:hover { background: var(--ink); color: var(--bone); }
.grotesque .app__note { color: #3A1212; font-size: 14px; line-height: 20px; }

.grotesque .app__shot { margin: 0; transform: rotate(-1.5deg); }
/* The screenshot carries the window's own rounded corners as transparency, so
   the shadow is drop-shadow (it follows those corners) rather than box-shadow
   (which follows the img's box and shows at the corners). Stacked: a tight one
   where the window meets the red, then a long soft one falling down and right,
   tinted toward the red so it doesn't go grey. */
.grotesque .app__shot img {
  display: block; width: 100%; height: auto;
  filter:
    drop-shadow(0 1px 2px rgb(58 18 18 / .3))
    drop-shadow(0 10px 16px rgb(58 18 18 / .3))
    drop-shadow(20px 40px 64px rgb(40 8 8 / .5));
}

/* ---------- Entries ---------- */
/* A masonry of columns (contest.js deals the covers in, left to right). Every
   other column starts lower, the columns drift at different speeds as the
   section scrolls, and each cover flickers on like a bad bulb the first time
   it comes into view. Reduced motion keeps the layout and drops the rest. */
.grotesque .entries { display: flex; flex-direction: column; gap: 56px; padding: 96px var(--gutter) 160px; overflow: clip; }
.grotesque .masonry { display: flex; align-items: flex-start; gap: 28px; }
.grotesque .masonry__col { display: flex; flex-direction: column; gap: 44px; flex: 1 1 0; min-width: 0; }
.grotesque .masonry__col:nth-child(even) { margin-top: 96px; }
.grotesque .tile { min-width: 0; }
.grotesque .tile a, .grotesque .tile > span { display: block; text-decoration: none; }
/* --ratio is the cover's own shape, set when it loads; 4:5 holds the space until then. */
.grotesque .tile__cover {
  position: relative; aspect-ratio: var(--ratio, 4 / 5); border-radius: 8px; overflow: clip; background: #1A1712;
  transition: transform 450ms cubic-bezier(.2, .7, .2, 1), box-shadow 450ms ease;
}
.grotesque .tile__cover img { width: 100%; height: 100%; object-fit: cover; }
.grotesque .tile a:hover .tile__cover {
  transform: translateY(-8px) rotate(var(--tilt));
  box-shadow: 0 28px 56px -20px rgb(237 49 50 / .55);
}

.grotesque .masonry.is-animated .tile { opacity: 0; }
.grotesque .masonry.is-animated .tile.is-in { animation: grotesque-tile-flicker 1100ms cubic-bezier(.2, .7, .2, 1) var(--delay, 0ms) both; }
@keyframes grotesque-tile-flicker {
  0%   { opacity: 0;   transform: translateY(64px) rotate(var(--tilt)); filter: grayscale(1) brightness(.3); }
  10%  { opacity: .85; }
  15%  { opacity: .1; }
  24%  { opacity: 1; }
  30%  { opacity: .35; }
  42%  { opacity: 1;   filter: grayscale(.5) brightness(1.5); }
  100% { opacity: 1;   transform: none; filter: none; }
}
@media (prefers-reduced-motion: reduce) {
  .grotesque .tile a:hover .tile__cover { transform: none; }
}
.grotesque .tile__badge {
  position: absolute; top: 8px; left: 8px; padding: 3px 8px; border-radius: 999px;
  background: var(--red); color: var(--ink);
  font-family: "Termina", system-ui, sans-serif; font-weight: 600;
  font-size: 10px; line-height: 14px; letter-spacing: 0.12em; text-transform: uppercase;
}
.grotesque .tile__handle { padding-top: 12px; color: var(--bone-dim); font-size: 15px; line-height: 20px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.grotesque .tile a:hover .tile__handle { color: var(--bone); }
.grotesque .load-error { color: var(--red); font-size: 17px; line-height: 26px; }

/* ---------- Narrower screens ---------- */
@media (max-width: 1240px) {
  .grotesque { --gutter: 64px; }
  .grotesque .hero { --art-edge: calc(var(--gutter) + 900px); }
  .grotesque .winners__body { flex-direction: column; }
  .grotesque .first, .grotesque .places { flex: none; width: 100%; max-width: 744px; }
  .grotesque .brief { flex-direction: column; gap: 48px; }
  .grotesque .brief__copy, .grotesque .prizes { flex: none; width: 100%; max-width: 640px; }
}

@media (max-width: 900px) {
  .grotesque { --gutter: 32px; }
  /* The house goes full width on top, its foot dissolving under the copy. */
  .grotesque .hero { flex-direction: column; align-items: stretch; min-height: 0; }
  .grotesque .hero__art { position: relative; inset: auto; aspect-ratio: var(--art-ratio); -webkit-mask: none; mask: none; }
  .grotesque .hero__art::before, .grotesque .hero__light {
    width: 100%; background-position: center;
    -webkit-mask-image: url("img/house-fade-foot.svg"); mask-image: url("img/house-fade-foot.svg");
  }
  .grotesque .hero__copy { width: 100%; margin-top: -96px; padding: 0 var(--gutter) 64px; }
  .grotesque .hero__title { font-size: 80px; line-height: 74px; }
  .grotesque .section-head { flex-direction: column; align-items: flex-start; gap: 24px; }
  .grotesque .winners__intro { flex: none; }
  .grotesque .winners { padding-block: 80px; }
  /* The app stacks: pitch, then the screenshot. */
  .grotesque .app { grid-template-columns: minmax(0, 1fr); gap: 56px; padding-block: 80px 88px; }
  .grotesque .app__title { font-size: 52px; line-height: 52px; }
}

@media (max-width: 640px) {
  .grotesque { --gutter: 20px; --tear-w: 760px; --tear-h: 40px; padding-bottom: 64px; }
  .grotesque .app { padding-block: 64px 72px; gap: 44px; }
  .grotesque .app__title { font-size: 40px; line-height: 42px; }
  .grotesque .app__body { font-size: 17px; line-height: 26px; }
  .grotesque .app__actions { flex-direction: column; align-self: stretch; }
  .grotesque .hero__title { font-size: 60px; line-height: 56px; }
  .grotesque .hero__tagline { font-size: 32px; line-height: 38px; }
  .grotesque .section-title { font-size: 56px; line-height: 56px; }
  .grotesque .section-title--small { font-size: 48px; line-height: 48px; }
  .grotesque .first { flex-direction: column; align-items: stretch; gap: 24px; padding: 20px; }
  .grotesque .first__cover { flex: none; }
  .grotesque .first__cover img { width: 100%; height: auto; aspect-ratio: 4 / 5; }
  .grotesque .brief { padding-block: 64px; }
  .grotesque .brief__title { font-size: 36px; line-height: 40px; }
  .grotesque .prizes { padding: 24px; }
  .grotesque .hero__copy { margin-top: -48px; }
  .grotesque .entries { gap: 40px; padding-block: 64px 96px; }
  .grotesque .masonry { gap: 14px; }
  .grotesque .masonry__col { gap: 28px; }
  .grotesque .masonry__col:nth-child(even) { margin-top: 56px; }
  .grotesque .tile__handle { padding-top: 8px; font-size: 13px; line-height: 18px; }
}
