/* Styles of this site, linked while this file exists.
   The layout module brings the structure; everything here is z'3280's own look.
   Colors come from identity as --color and --color-bg — the rest is mixed from those two. */

@import url('https://fonts.googleapis.com/css2?family=Caveat:wght@400;600&family=Jost:wght@300;400;500&family=Londrina+Outline&family=Londrina+Solid&family=Oswald:wght@500;600;700&display=swap');

html {
  --width: 68rem; /* measure of header, content and footer */

  --font-1: 'Jost', system-ui, sans-serif; /* u2 reads this one */
  --font-head: 'Oswald', system-ui, sans-serif;
  --font-hand: 'Caveat', cursive;
  --font-logo: 'Londrina Outline', 'Londrina Solid', system-ui, sans-serif;

  --radius: .25rem;

  font-weight: 300;
  line-height: 1.65;
}

/* Base typography, deliberately at zero specificity: a content module that wants a
   different heading — the oversized page title, say — must be able to say so without
   fighting an id selector. */
:where(h1, h2, h3, h4) {
  font-family: var(--font-head);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
  line-height: 1.15;
  margin: 0 0 .6em;
}

:where(h1) { font-size: clamp(1.5rem, 3vw, 2.1rem) }
:where(h2) { font-size: clamp(1.25rem, 2.2vw, 1.6rem) }
:where(h3) { font-size: 1.1rem }
x:where(p) { margin: 0 0 1.1em }

/* the site is monochrome: a link is marked by weight and rule, never by hue */
:where(a) { color: inherit }

#container {
  font-family: var(--font-1);

  #head {
    background: color-mix(in srgb, var(--color-bg), white 50%);

    nav a {
      font-size: .92rem;
      padding: .2em 0;
    }

    /* the call to action: whatever link the editor puts in that slot becomes the button */
    [qcms-name=action] {
      p { margin: 0 }
      a {
        display: inline-block;
        font-size: .78rem;
        text-transform: uppercase;
        letter-spacing: .13em;
        text-decoration: none;
        padding: .8em 1.5em;
        border: 1px solid var(--color);
        transition: background .2s, color .2s;
      }
      a:hover {
        background: var(--color);
        color: var(--color-bg);
      }
    }
  }

  #foot {
    font-size: .92rem;

    h2, h3 {
      font-size: .8rem;
      letter-spacing: .14em;
      margin-bottom: 1.1em;
    }
  }
}

/* Links inside content that carry the button look — set by the editor as a class. */
.btn {
  border-radius: var(--radius);
  display: inline-block;
  font-size: .78rem;
  text-transform: uppercase;
  letter-spacing: .13em;
  text-decoration: none;
  padding: .95em 1.8em;
  border: 1px solid var(--color);
  transition: background .2s, color .2s;
}
.btn:hover { background: var(--color); color: var(--color-bg) }
.btn-solid { background: var(--color); color: var(--color-bg) }
.btn-solid:hover { background: none; color: var(--color) }

/* Rule under a heading, as in the design. */
.rule::after {
  content: '';
  display: block;
  width: 4.5rem;
  height: 2px;
  background: var(--color);
  margin-top: .55em;
}

/* The hero opens with the wordmark — the module sizes it, the face is ours. */
/* Londrina has a single weight; anything bolder is synthesised and turns fat. */
[qcms-mod="cont.luca.pagehead"] .title {
  font-family: var(--font-logo);
  font-weight: 400;
}

/* The sketched arrow beside the handwritten note: it comes down from the buttons
   above and its head runs into the first word, the way the drawing has it. */
[qcms-mod="cont.luca.hero"] .note {
  display: flex;
  align-items: flex-start;
  gap: .15rem;
}
[qcms-mod="cont.luca.hero"] .note::before {
  content: '';
  flex: none;
  width: 1.5rem;
  height: 1.6rem;
  margin-left: 1rem;
  margin-top: -.5rem;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 34' fill='none' stroke='%231a1714' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 2C3 14 6 25 21 29'/%3E%3Cpath d='M21 29 13 28M21 29 17 21'/%3E%3C/svg%3E") no-repeat center / contain;
}

[qcms-mod="cont.luca.hero"] {
  .lead { font-family: var(--font-logo); font-weight: 400 }
  .sub { font-family: var(--font-head); font-weight: 500 }
}

/* cms-image2 is width:100% and takes its height from its aspect ratio — so the width has
   to come from the link around it, otherwise it collapses to its min-width. */
.head-logo { flex: none; width: 7rem }
#foot .foot-brand > a { display: block; width: 9rem; margin-bottom: .8rem }

/* The drawing is ink on white — multiply lets the paper show through it. */
#foot .foot-grid > :is(img, cms-image2) { mix-blend-mode: multiply }

/* ---------- Hand-drawn strokes ----------
   The frames and rules of the design are drawn, not ruled. A displacement filter on a
   border-only layer gives that without touching the text it surrounds — the filter would
   otherwise blur and warp the letters. */

/* Buttons: the border moves to a pseudo-element, the element itself keeps only its fill.
   Only where a button is actually meant — in a note or a feature the action is a plain
   text link, and a drawn frame around it would be wrong. */
#container [qcms-name=action] a,
#container :is([qcms-mod="cont.luca.hero"], [qcms-mod="cont.luca.notebar"]) [qcms-name=actions] a,
#container .btn {
  position: relative;
  border-color: transparent !important;
}

#container [qcms-name=action] a::before,
#container :is([qcms-mod="cont.luca.hero"], [qcms-mod="cont.luca.notebar"]) [qcms-name=actions] a::before,
#container .btn::before {
  content: '';
  position: absolute;
  inset: 0;
  border: 2px solid currentColor;
  border-radius: var(--radius);
  filter: url(#sketch);
  pointer-events: none;
}

/* An emphatic button is a filled one — there the drawn frame would only muddy the edge. */
#container [qcms-mod="cont.luca.hero"] [qcms-name=actions] a:first-of-type::before {
  border-color: transparent;
}

/* Rules under headings, drawn with the same hand. */
#container .rule::after {
  filter: url(#sketch);
}

/* The current page in the navigation is underlined by hand as well. */
#container #head nav a {
  position: relative;
  border-bottom-color: transparent;
}
#container #head nav :is(.cmsActive, .cmsInside) > a::after,
#container #head nav a:hover::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -.15em;
  border-bottom: 2px solid currentColor;
  filter: url(#sketch);
}



/* ---------- The menu lies on a placemat ----------
   A lighter sheet under the dishes, with the same torn edge as the note cards. */
#container [qcms-mod="cont.luca.menu"] .mat {
  position: relative;
  isolation: isolate;
  padding: clamp(1.5rem, 4vw, 3rem);
}
#container [qcms-mod="cont.luca.menu"] .mat::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: color-mix(in srgb, var(--color-bg), white 65%);
  /* drop-shadow follows the torn outline; box-shadow would trace the rectangle behind it */
  filter: url(#deckle) drop-shadow(2px 2px 4px #0003);
}


/* ---------- Blocks fade in as they come up ----------
   Pure CSS (scroll-driven animation): no JS state, so content is never left invisible
   because a script failed or is still loading. Without browser support the blocks are
   simply there. Applies to the blocks of a page, not to what sits inside them. */

@keyframes reveal {
  from { opacity: 0; translate: 0 1.5rem }
  to   { opacity: 1; translate: 0 0 }
}

@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    #content > [qcms-name=main] > * {
      animation: reveal linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 55%;
    }
  }
}

