/* Melly Labs — the wordmark page
 * =============================
 *
 * One screen. The name is the page: letters built out of flat shapes, drawn
 * rather than typed, with a green glow sitting behind them. Everything else is
 * small and at the edges: four words of navigation, the statement, a link.
 *
 * Nothing moves and nothing scrolls. Choosing "products" raises a sheet with
 * the two of them and the way in.
 *
 * Its own stylesheet. The film version and the quiet version keep theirs.
 */

/* Cera Pro is the studio's face. It is licensed, so it is not fetched from a
 * CDN: drop the files in assets/fonts/ and they are picked up here. Until they
 * are there, Poppins stands in. It is the nearest geometric sans that can be
 * served for free, close enough that the layout does not move when the real
 * one arrives.
 */
@font-face {
  font-family: 'Cera Pro'; font-style: normal; font-weight: 300; font-display: swap;
  src: url('fonts/CeraPro-Light.woff2') format('woff2'),
       url('fonts/CeraPro-Light.otf') format('opentype'),
       url('fonts/Cera%20Pro%20Regular.otf') format('opentype');
}
@font-face {
  font-family: 'Cera Pro'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('fonts/CeraPro-Regular.woff2') format('woff2'),
       url('fonts/CeraPro-Regular.otf') format('opentype'),
       url('fonts/Cera%20Pro%20Regular.otf') format('opentype');
}

:root {
  --ink: #08090b;
  --ink-2: rgba(8, 9, 11, 0.55);
  --paper: #fff;
  --green: #00ffaa;   /* the artwork's green, at the middle of the glow */
  --cyan: #5ef2d6;
  --blue: #2323e6;
  --sans: 'Cera Pro', 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --edge: clamp(18px, 3.6vw, 56px);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  font-family: var(--sans); color: var(--ink); background: var(--paper);
  line-height: 1.45; -webkit-font-smoothing: antialiased;
  height: 100vh; height: 100dvh; overflow: hidden;
}

a { color: inherit; text-decoration: none; }
:focus-visible { outline: 2px solid var(--green); outline-offset: 4px; }
::selection { background: var(--green); color: var(--ink); }

/* A heading the page still has, for anything reading rather than looking. */
.sr {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

.skip { position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--ink); color: #fff; padding: 12px 18px; }
.skip:focus { left: 12px; top: 12px; }

/* --- The edges ------------------------------------------------------------- */



.dots {
  position: fixed; left: var(--edge); bottom: calc(var(--edge) - 6px); z-index: 30;
  display: flex; align-items: center; gap: 5px;
}


/* --- The two floods ---------------------------------------------------------
 * The whole screen takes the colour. Nothing else moves: the name stays where
 * it is, and on blue the outline turns white so the letters keep their edge.
 */
body { transition: background .5s ease; }
body.on-green { background: var(--green); }
body.on-blue { background: var(--blue); color: #fff; }
/* Blue drops the outline. Hidden rather than removed: the outline is the one
   layer in the flow, so taking it out would collapse the block and the glow and
   the fill, which hang off it, would go with it. */
body.on-blue .type { visibility: hidden; }
body.on-blue nav, body.on-blue .star, body.on-blue .out, body.on-blue .say { color: #fff; }
@media (prefers-reduced-motion: reduce) { body { transition: none; } }

.out {
  position: fixed; right: var(--edge); bottom: calc(var(--edge) - 8px); z-index: 30;
  font-size: clamp(16px, 1.28vw, 20px); font-weight: 300;
}

/* --- The name -------------------------------------------------------------- */

main {
  position: relative; z-index: 10; height: 100vh; height: 100dvh;
  display: grid; align-content: center; justify-items: center;
}

/* The whole name, centred, rather than running off both edges. The glow still
   spills past it, which is the blur doing it and not the drawing. */
/* Wider than the window on purpose: the first and last letters run off both
   edges, so the name reads as bigger than the screen holding it. */
.mark {
  /* 103, not 102: the letters fill 99% of the artwork's box, so this lands them
     at 102 of the screen and keeps the same whisker of a cut at both edges. */
  position: relative; width: 103vw; margin-left: -1.5vw;
}
.mark img { display: block; width: 100%; height: auto; }

/* The glow and the fill sit exactly over the outline, which is the one that
   gives the block its height. */
.mark .fill { position: absolute; inset: 0; }

/* Paper shows glow 1, blue shows glow 3. */
.mark .deep { display: none; }
body.on-blue .mark .paper { display: none; }
body.on-blue .mark .deep { display: block; }
.mark .fill { z-index: 1; }
.mark .type { position: relative; z-index: 2; }


/* --- On a phone the name stands up -----------------------------------------
 * Five letters this wide across a phone leaves them the height of a fingernail.
 * So the name takes a quarter turn and reads bottom to top, the way a spine
 * does, at the height of the screen rather than the width of it. The statement
 * stays the way round the reader is: the mark is a picture, the sentence is
 * something to read.
 */
@media (max-width: 760px) {
  main { position: relative; }

  /* Turned, the name is tall and narrow. With the menu and the statement away,
     nothing needs the column beside it, so it stands in the middle. */



  .mark {
    position: absolute; top: 50%; left: 50%;
    /* The whole word, inside the screen: 92 rather than 103, so nothing is cut
       by the top or the bottom. svh, not vh, because on iOS vh is the screen
       without the browser's toolbars. */
    width: 92vh; width: 92svh; margin: 0;
    transform: translate(-50%, -50%) rotate(-90deg);
    transform-origin: center;
  }

  /* The name fills the height on a phone; the sentence over it is one thing too
     many. It stays on a screen, where there is room for both. */
  .say { display: none; }
}

/* --- What we do ------------------------------------------------------------ */

/* Out of the flow, so putting the sentence back does not lift the name off the
   middle of the screen. It hangs below the mark instead of pushing it. */
.say {
  /* Sitting on the same line as the two corners: linkedin at one side, the
     chevrons at the other, the sentence between them. */
  position: absolute; bottom: calc(var(--edge) - 8px);
  /* Starting under the e of melly, taken from the drawing: the e begins 590 of
     1983 across the artwork, and the artwork is 103vw wide sitting 1.5vw off
     the left edge. */
  left: 29.12vw; margin: 0;
  font-size: clamp(1.8rem, 3.5vw, 3.4rem); font-weight: 400; line-height: 1.22;
  letter-spacing: -0.01em;
}

/* One rule per line, all the same length: the width of the widest line, which
   is what the block measures. An underline would stop at the last word of each
   line and give three different lengths. */
.say span {
  display: block; white-space: nowrap;
  border-bottom: 2px solid currentColor;
  padding-bottom: .1em; margin-bottom: .12em;
}

/* --- The sheet ------------------------------------------------------------- */

.veil {
  position: fixed; inset: 0; z-index: 40;
  background: rgba(8, 9, 11, .3); backdrop-filter: blur(3px);
  opacity: 0; pointer-events: none; transition: opacity .4s ease;
}
.veil.open { opacity: 1; pointer-events: auto; }

.sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
  background: var(--paper); color: var(--ink);
  border-top: 1px solid rgba(8, 9, 11, .14);
  padding: clamp(34px, 6vh, 74px) var(--edge) clamp(30px, 5vh, 58px);
  transform: translateY(101%);
  transition: transform .55s cubic-bezier(.22, 1, .28, 1);
  height: 86vh; height: 86dvh;
  display: flex; align-items: center; overflow-y: auto;
  box-shadow: 0 -22px 64px rgba(8, 9, 11, .16);
}
.sheet.open { transform: none; }

.sheet-in { max-width: 1180px; margin: 0 auto; width: 100%; }
.sheet-top {
  display: flex; justify-content: space-between; align-items: baseline; gap: 20px;
  border-bottom: 1px solid rgba(8, 9, 11, .14);
  padding-bottom: clamp(14px, 2.4vh, 24px);
}
.sheet h2 {
  font-weight: 300; font-size: clamp(2rem, min(5.6vw, 9vh), 4rem);
  letter-spacing: -0.03em; line-height: 1;
}
.shut { border: 0; background: none; cursor: pointer; padding: 6px;
  font: inherit; font-size: .9rem; color: var(--ink-2); }
.shut:hover { color: var(--ink); }

/* Two products, side by side, because there are two. */
.two {
  display: grid; grid-template-columns: 1fr; gap: clamp(26px, 4vw, 64px);
  margin-top: clamp(24px, 4vh, 44px);
}
@media (min-width: 860px) { .two { grid-template-columns: 1fr 1fr; } }

.one h3 {
  font-weight: 300; font-size: clamp(1.7rem, 3vw, 2.4rem);
  letter-spacing: -0.025em; line-height: 1;
}
.one p {
  font-weight: 300; font-size: clamp(.98rem, 1.2vw, 1.12rem);
  color: var(--ink-2); margin-top: 14px; max-width: 42ch;
}
.one ul { list-style: none; display: grid; gap: 9px; margin-top: 20px; }
.one li {
  font-size: .88rem; font-weight: 300; color: var(--ink-2);
  padding-left: 18px; position: relative;
}
.one li::before {
  content: ""; position: absolute; left: 0; top: .62em;
  width: 8px; height: 1px; background: var(--green);
}

.do { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin-top: 26px; }
.btn {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 15px 28px; background: var(--ink); color: #fff;
  font-size: .92rem; font-weight: 400; transition: background .2s ease;
}
.btn:hover { background: #123; }
.btn.green { background: var(--green); color: var(--ink); }
.btn.green:hover { background: #00c97d; }
.fine { font-size: .8rem; font-weight: 300; color: var(--ink-2); }

@media (max-height: 620px) {
  .sheet { height: auto; max-height: 92vh; display: block; }
}
@media (prefers-reduced-motion: reduce) {
  .sheet, .veil, .star, nav button::after, nav a::after { transition: none; }
}

/* --- The name, in the corner ------------------------------------------------
 * A phone hides the menu behind the star, which leaves the top left empty and
 * the page unnamed. On a screen the bar already begins with it, so it shows
 * only where it is needed.
 */
.home {
  display: none;
  position: fixed; top: var(--edge); left: var(--edge); z-index: 40;
  font-size: clamp(16px, 1.28vw, 20px); font-weight: 300;
}
@media (max-width: 760px) { .home { display: block; } }

/* --- The star, and the menu under it ----------------------------------------
 * The only thing in the corner is the mark itself. What it opens sits directly
 * beneath, right-aligned to it, so the eye travels one line rather than across
 * the page.
 */
.star {
  border: 0; background: none; padding: 0; cursor: pointer;
  color: var(--ink);
  position: fixed; top: var(--edge); right: var(--edge); z-index: 40;
  transition: transform .5s cubic-bezier(.2,.7,.3,1);
}
.star svg {
  display: block;
  width: clamp(28px, 2.6vw, 40px); height: clamp(28px, 2.6vw, 40px);
}

/* Black on paper, white on either colour. */
body.on-blue .star { color: #fff; }
body.on-blue .home { color: #fff; }
.star:hover { transform: rotate(90deg); }
.star[aria-expanded="true"] { transform: rotate(90deg); }

nav#menu {
  position: fixed; top: calc(var(--edge) + 34px); right: var(--edge); z-index: 40;
  display: flex; flex-direction: column; align-items: flex-end; gap: 11px;
  font-size: clamp(16px, 1.28vw, 20px); font-weight: 300;
}
nav#menu[hidden] { display: none; }
nav#menu a, nav#menu button {
  font: inherit; color: inherit; background: none; border: 0; padding: 0;
  cursor: pointer; position: relative;
}
nav#menu a::after, nav#menu button::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -3px; height: 2px;
  background: currentColor; transform: scaleX(0); transform-origin: right;
  transition: transform .16s cubic-bezier(.2,.7,.3,1);
}
nav#menu a:hover::after, nav#menu button:hover::after { transform: scaleX(1); }

/* On a screen the four ways in are a bar at the top left, always there. The
   star stays in its corner as the mark, and stops being a control: there is
   nothing left for it to open. Below 760 it is the other way round, and the
   menu lives under the star. */
@media (min-width: 761px) {
  nav#menu, nav#menu[hidden] {
    display: flex; flex-direction: row; align-items: baseline;
    position: fixed; top: var(--edge); left: var(--edge); right: auto;
    gap: clamp(18px, 2.6vw, 38px);
  }
  nav#menu a::after, nav#menu button::after { transform-origin: left; }
  .star { cursor: default; }
  .star:hover { transform: rotate(90deg); }
}

/* The heart beside "for you": the same colour as the words it sits with, so it
   reads as part of them rather than as a badge. */
nav#menu .heart {
  width: .82em; height: .82em; display: inline-block; vertical-align: -.03em;
  fill: currentColor;
}

/* "for you" behaves differently from the rest of the menu: no line sweeping
   under it, the whole thing grows instead, words and heart together. */
nav#menu a[href="for-you.html"] {
  display: inline-block; transform-origin: left center;
  transition: transform .25s cubic-bezier(.2,.7,.3,1);
}
nav#menu a[href="for-you.html"]::after { content: none; }
nav#menu a[href="for-you.html"]:hover { transform: scale(1.14); }
@media (max-width: 760px) {
  nav#menu a[href="for-you.html"] { transform-origin: right center; }

  /* On a phone the menu is the whole screen rather than a list tucked under the
     star: four targets the size of a thumb, centred, on the studio's green. A
     dropdown that small was a thing to aim at rather than a thing to press. */
  nav#menu {
    position: fixed; inset: 0; z-index: 50;
    top: 0; right: 0; bottom: 0; left: 0;
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    gap: clamp(20px, 4.5vh, 40px);
    background: var(--green); color: var(--ink);
    font-size: clamp(1.9rem, 9vw, 3rem); font-weight: 300;
    text-align: center;
  }
  nav#menu[hidden] { display: none; }

  /* The star stays above it, because it is also the way out. Black on the
     green, whatever ground the page was on underneath. */
  .star { z-index: 60; }
  body.menu-open .star { color: var(--ink); }

  /* Nothing scrolls behind an open menu. */
  body.menu-open { overflow: hidden; }

  /* The line under each item has nothing to add at this size. */
  nav#menu a::after, nav#menu button::after { content: none; }
}

body.on-blue nav#menu { color: #fff; }
@media (prefers-reduced-motion: reduce) { .star { transition: none; } }

/* --- The chevrons -----------------------------------------------------------
 * Three of them, one per ground. The one you are on is drawn heavy and the
 * others stay hairlines, so the set reads as a position rather than as three
 * separate buttons. They never change colour: weight carries all of it.
 */
.dots button {
  background: none; border: 0; padding: 0; cursor: pointer; display: block;
}
.dots svg {
  display: block; overflow: visible;
  width: clamp(15px, 1.3vw, 20px); height: auto;
}
.dots polyline {
  fill: none; stroke: var(--ink); stroke-width: 2;
  stroke-linecap: butt; stroke-linejoin: miter;
  transition: stroke-width .2s ease, stroke .2s ease;
}

/* Where you are: heavy, the other two hairlines. */
.dots [aria-pressed="true"] polyline { stroke-width: 6; }

/* With the pointer in the set, the rest thin away and only the one under it is
   heavy. Weight says everything here; colour says nothing. These two rules sit
   in this order on purpose: the thinning has to beat the one you are on, and
   the hovered one has to beat the thinning. */
.dots:hover polyline { stroke-width: 1.2; }
.dots button:hover polyline { stroke-width: 6; }

body.on-blue .dots polyline { stroke: #fff; }

/* The phone's menu panel is green whichever ground the page is on, so its items
   stay black there. Without this the blue rule above would turn them white on
   green, which is barely readable. */
@media (max-width: 760px) {
  body.on-blue nav#menu { color: var(--ink); }
}
