/* ==========================================================================
   Holly Writes — hollywrites.me
   White page, near-black text, one coral. Body copy is Courier throughout;
   the serif is display only; the sans is reserved for nav, footer and buttons.
   #ff5055 is the editor's pen: it marks things and it drives actions.
   ========================================================================== */

:root {
  --paper:    #ffffff;
  --ink:      #231f20;
  --ink-soft: #55504f;
  --rule:     #231f20;
  --hair:     #cfcbc9;
  --pen:      #ff5055;

  /* Playfair Display stands in for the Canva display serif, which the saved
     site only references by an internal font ID. Swap it here if you find the
     real one; nothing else needs to change. */
  --font-display: "Playfair Display", Georgia, "Times New Roman", serif;
  --font-body: "Courier Prime", "Courier New", Courier, monospace;
  --font-ui: "Instrument Sans", -apple-system, BlinkMacSystemFont,
             "Segoe UI", Helvetica, Arial, sans-serif;

  --step--1: clamp(0.8rem, 0.77rem + 0.14vw, 0.88rem);
  --step-0:  clamp(0.86rem, 0.83rem + 0.17vw, 0.96rem);
  --step-1:  clamp(1.1rem, 1.02rem + 0.34vw, 1.32rem);
  --step-2:  clamp(1.6rem, 1.3rem + 1.4vw, 2.6rem);
  --step-3:  clamp(2.1rem, 1.5rem + 2.8vw, 4rem);
  --display: clamp(2.75rem, 9.5vw, 8rem);

  --gutter: clamp(1rem, 4vw, 3rem);
  /* One knob for every frame's inset. Raise or lower this alone. */
  --frame-pad: clamp(1.25rem, 2.4vw, 2rem);
  --rhythm: clamp(2.5rem, 7vh, 4.5rem);

  /* 1200px of content is the common ceiling for a text-led site: wide enough
     for the four-column row, narrow enough that lines stay readable and the
     portrait doesn't inflate on a 27-inch monitor. */
  --shell: 75rem;
}

/* --------------------------------------------------------------- reset -- */

*, *::before, *::after { box-sizing: border-box; }
body, h1, h2, h3, p, figure, dl, dd, ul, ol { margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

body {
  background-color: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.75;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  /* Caps the whole page -- nav, frames and footer stay in one column. */
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* height:auto matters: the HTML height attribute applies as a presentational
   hint, so an img sized in CSS otherwise keeps its literal attribute height
   and blows the layout apart. */
img, svg { max-width: 100%; height: auto; display: block; }

/* Base link colour. Without this, links outside .prose fall back to browser
   blue, which is wrong against this palette. */
a { color: var(--ink); text-underline-offset: 2px; }
a:hover { color: var(--pen); }

:where(a, button, input, textarea):focus-visible {
  outline: 2px solid var(--pen);
  outline-offset: 3px;
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  top: 0; left: var(--gutter);
  transform: translateY(-140%);
  background: var(--ink);
  color: var(--paper);
  padding: 0.6rem 1rem;
  z-index: 20;
  text-decoration: none;
}
.skip-link:focus { transform: translateY(0); }

/* ----------------------------------------------------------------- nav -- */

.masthead { padding-block: clamp(1rem, 2.5vh, 1.6rem); }

.nav ul {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.75rem clamp(1rem, 4vw, 3rem);
  list-style: none;
}

/* Caps and permanently underlined: that is how the design sets the nav. */
.nav a {
  font-family: var(--font-ui);
  font-size: clamp(0.85rem, 1.15vw, 1.15rem);
  font-weight: 700;
  text-transform: uppercase;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 2px;
}

.nav a[aria-current="page"] { text-decoration-color: var(--pen); }

/* --------------------------------------------------------------- frame -- */

.frame {
  border: 1px solid var(--rule);
  padding: var(--frame-pad);
  position: relative;
}

/* A frame inside a frame would otherwise stack two full insets -- on Hire Me
   that put 112px between the page edge and the first label, against roughly
   30px in the design. The inner one is tighter. */
.frame .frame { padding: clamp(0.75rem, 1.2vw, 0.9rem); }


/* ---------------------------------------------------------- typography -- */

h1, h2, h3 { font-family: var(--font-display); font-weight: 700; line-height: 1.1; }

h1 { font-size: var(--step-3); }
h2 { font-size: var(--step-2); }

/* Courier needs a shorter measure than a proportional face to stay readable. */
p { max-width: 58ch; }
.prose > * + * { margin-top: 1.1em; }

/* Page title with a mark alongside it, as on every interior page. */
.title-row {
  display: flex;
  align-items: flex-start;
  gap: clamp(0.5rem, 2vw, 1.25rem);
  flex-wrap: wrap;
}

.title-row h1 { margin: 0; }

/* The strokes sit above the title's cap height in the design, not centred
   beside it. Scaled off --step-3 so the offset tracks the title as it grows. */
.title-row__mark {
  width: clamp(1.75rem, 3.5vw, 3rem);
  margin-top: calc(var(--step-3) * -0.32);
}

/* The swoosh that trails off the About Me title. */
.title-row__trail {
  /* Kept narrow enough to stay on the same line as the title at its largest
     size, rather than wrapping under it. */
  width: clamp(4rem, 8vw, 7rem);
  align-self: center;
}

/* The squiggle trails off below the About Me baseline; the star trail on Hire
   Me runs level with the title. */
/* Sized and placed off the title, from the Canva design: the trail is about
   1.9x the title's font size wide and starts near its baseline. */
.title-row__trail--low {
  width: calc(var(--step-3) * 2.22);
  margin-top: calc(var(--step-3) * 0.62);
  margin-left: calc(var(--step-3) * 0.05);
  align-self: flex-start;
}

/* On About Me the strokes sit left of the title and the squiggle's loop falls
   at its right-hand end, so both are mirrored. The marks on What I Do and
   Hire Me sit right of their titles and are used as drawn. */
.title-row__mark--flip,
.title-row__trail--flip { transform: scaleX(-1); }
.title-row__trail--wide {
  width: clamp(7rem, 16vw, 13rem);
  margin-left: clamp(1rem, 4vw, 3.5rem);
}

/* ---------------------------------------------------------------- hero -- */

.hero {
  display: grid;
  justify-items: center;
  /* The arrow sits about 1.03em above the wordmark, where em is --display.
     Scaling the top padding off the same variable keeps it inside the frame
     at every width. A vh-based value broke on short windows. */
  padding-top: calc(var(--display) * 1.15);
  padding-bottom: clamp(2rem, 9vh, 6rem);
  position: relative;
}

@media (max-width: 40rem) {
  /* The arrow is hidden below this width, so the headroom isn't needed. */
  .hero { padding-top: clamp(1.5rem, 6vh, 3rem); }
}

/* Sized here so the marks inside can use em and % against the wordmark and
   track it at every viewport width. */
.hero__wordmark {
  position: relative;
  display: inline-block;
  font-size: var(--display);
  line-height: 1;
}

.hero__title {
  font-family: var(--font-display);
  font-size: 1em;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.01em;
  text-align: center;
}

.hero__byline {
  font-size: clamp(0.95rem, 2vw, 1.6rem);
  letter-spacing: 0.16em;
  text-align: center;
  line-height: 1.9;
  /* The scribble is absolutely positioned and so takes up no flow space.
     This reserves the gap for it, scaled off the wordmark like everything
     else in the hero. */
  margin-top: calc(var(--display) * 1.7);
  max-width: none;
}

/* Marks scattered around the wordmark. Decorative, so empty alt text, and
   they drop out on narrow screens where they would collide with the type. */
.hero__mark { position: absolute; pointer-events: none; user-select: none; }

.hero__mark--arrow {
  width: 25%;
  left: 38%;
  bottom: calc(100% + 0.21em);
  /* The saved arrow points left; the design sweeps it right. */
  transform: scaleX(-1);
}

/* Rotated a half turn so the strokes fan out from the upper right toward the
   lower left, away from the wordmark. A plain scaleX(-1) mirror gets the
   horizontal stroke on the wrong end of the fan. */
/* Off the lower-left corner: starts about four fifths of the way down the
   wordmark and runs past the baseline, as in the design. */
.hero__mark--dashes {
  width: 8.6%;
  right: calc(100% + 0.12em);
  top: 0.82em;
  transform: rotate(180deg);
}

/* Centred directly under the wordmark and sized against it, taken from the
   design: 24.2% of the wordmark's width, its centre within a pixel of the
   wordmark's own centre, sitting just below the baseline. */
.hero__mark--scribble {
  width: 24.2%;
  left: 37.9%;
  /* The box spans the whole gap down to the byline and object-fit centres the
     artwork inside it, so the scribble sits midway between the two without
     hard-coding its height. */
  top: 100%;
  height: calc(var(--display) * 1.7);
  object-fit: contain;
}

.hero__mark--underline {
  position: static;
  width: clamp(7.5rem, 17vw, 13.5rem);
  margin-top: clamp(2rem, 5vh, 3.5rem);
}

@media (max-width: 40rem) {
  .hero__mark--arrow, .hero__mark--dashes { display: none; }
}

/* ------------------------------------------------------------ what i do -- */

.work {
  display: grid;
  gap: clamp(1.75rem, 3vw, 2.5rem);
  margin-top: clamp(2rem, 5vw, 3.5rem);
  margin-left: clamp(1rem, 1vw, 1.5rem);
}

@media (min-width: 40rem)  { .work { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 62rem)  { .work { grid-template-columns: repeat(4, 1fr); } }

/* Illustrations vary in proportion, so give them a shared box and sit them
   on a common baseline instead of scaling each to the same width. */
.work__icon {
  height: clamp(6rem, 11vw, 11rem);
  display: flex;
  align-items: flex-end;
  justify-content: flex-start;
  margin-bottom: 1.5rem;
}

.work__icon img { max-height: 100%; width: auto; }

/* The magnifier faces the other way in the design. */
.work__icon--flip img { transform: scaleX(-1); }

.work h2 { font-family: var(--font-body); font-size: var(--step-1); font-weight: 700; }
.work p {
  margin-top: 0.75rem;
  max-width: none;
  text-align: left;
  hyphens: auto;
}

/* --------------------------------------------------------------- about -- */

.about { display: grid; gap: clamp(1.5rem, 4vw, 3rem); align-items: start; }

@media (min-width: 54rem) {
  /* Two columns: portrait and name block on the left, text box and resume
     link on the right. Each side stays in its own wrapper so that on narrow
     screens the photo and her name stack together rather than being split by
     the About Me box. */
  .about {
    grid-template-columns: 0.85fr 1.15fr;
    column-gap: clamp(2rem, 5vw, 4rem);
  }
}

.portrait {
  width: 100%;
  aspect-ratio: 8 / 7;
  object-fit: cover;
  object-position: center 20%;
  border-radius: 18px;
  /* Tying this to the neighbouring box's exact height needs JS or subgrid, so
     this caps it instead. Together with --shell it stops the portrait growing
     to fill a wide window, which was the actual complaint. */
  max-height: 30rem;
}

.about__name {
  font-family: var(--font-display);
  font-size: var(--step-2);
  margin-top: 1.5rem;
}

.about__role { line-height: 1.6; margin-top: 0.5rem; }

.about__sparkles {
  height: clamp(5.75rem, 12.5vw, 10.5rem);
  width: auto;
  margin-top: 1.5rem;
  /* The asset draws the small star above the large one and to its right.
     The design has the large one on top with the small one below-left, which
     is a half turn -- a vertical flip alone leaves the small star on the
     wrong side. */
  transform: rotate(180deg);
}

@media (min-width: 54rem) {
  /* Sits beside the name block, as in the design. */
  .about__identity { display: flex; align-items: center; gap: clamp(1.5rem, 5vw, 4rem); }
  .about__sparkles {
    /* Nudged down and right of the name block. */
    margin-top: clamp(1rem, 2.5vw, 2.25rem);
    margin-left: clamp(0.5rem, 2vw, 1.75rem);
    flex: none;
  }
}

.about__resume {
  display: block;
  text-align: right;
  font-size: 1.75rem;
  margin-top: 1.25rem;
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* -------------------------------------------------------------- button -- */

.button {
  display: inline-block;
  font-family: var(--font-ui);
  font-size: var(--step-0);
  font-weight: 700;
  text-transform: uppercase;
  line-height: 1;
  color: var(--paper);
  background-color: var(--pen);
  border: 2px solid var(--pen);
  padding: 0.85rem 1.7rem;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 120ms ease, color 120ms ease;
}

.button:hover:not(:disabled) { background-color: transparent; color: var(--pen); }
.button:disabled { opacity: 0.55; cursor: progress; }

.button--quiet { background-color: transparent; color: var(--ink); border-color: var(--ink); }
.button--quiet:hover:not(:disabled) { background-color: var(--ink); color: var(--paper); }

/* ---------------------------------------------------------------- form -- */

/* Full width inside the box, as in the design, rather than wrapping at a
   reading measure partway across. */
.form { margin-top: 0; max-width: none; }

.field { margin-bottom: 1.15rem; }

.field label {
  display: block;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
  margin-bottom: 0.35rem;
}

.field__hint {
  display: block;
  font-weight: 400;
  text-decoration: none;
  color: var(--ink-soft);
  line-height: 1.6;
  margin-bottom: 0.4rem;
  max-width: none;
}

/* Ruled lines rather than boxes, matching the design. */
.field input,
.field textarea {
  width: 100%;
  font-family: inherit;
  font-size: var(--step-0);
  color: var(--ink);
  background-color: transparent;
  border: 0;
  border-bottom: 1px solid var(--ink);
  border-radius: 0;
  padding: 0.5rem 0.25rem;
}

.field input:hover, .field textarea:hover { border-bottom-color: var(--pen); }
.field textarea { min-height: 7rem; resize: vertical; line-height: 1.7; }
.field input:user-invalid, .field textarea:user-invalid { border-bottom-color: var(--pen); }

/* Honeypot: people never see it, bots fill every input they find. */
.field--trap {
  position: absolute;
  left: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}

.form__footer { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; }

.form__status { font-size: var(--step--1); line-height: 1.6; max-width: 46ch; }
.form__status:empty { display: none; }
.form__status[data-state="error"] { color: var(--pen); font-weight: 700; }
.form__status[data-state="sending"] { color: var(--ink-soft); }

/* The standing "Thank you!" note that closes the form in the design. */
.form-note { margin-top: 1.5rem; border-top: 1px solid var(--hair); padding-top: 1rem; }
.form-note h2 {
  font-family: var(--font-body);
  font-size: var(--step-0);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
  margin-bottom: 0.25rem;
}
.form-note p { max-width: none; }

.confirmation { border-left: 3px solid var(--pen); padding-left: 1.5rem; margin-bottom: 2rem; }
.confirmation h2 { font-family: var(--font-display); margin-bottom: 0.4rem; }
.confirmation[hidden] { display: none; }

/* -------------------------------------------------------------- footer -- */

.colophon {
  position: relative;
  padding-top: clamp(1.75rem, 4vh, 2.75rem);
  /* A little deeper than the top: the decal overlaps the footer row and its
     line needs some clearance beneath. */
  padding-bottom: clamp(2.25rem, 5vh, 3.25rem);
}

/* Sits under the copyright line, left of the link columns. Decorative, so it
   drops out on narrow screens where it would crowd the stacked footer. */
/* Overlaps the footer row, starting just right of the copyright and running
   under the link columns, as in the design. */
.colophon__decal {
  position: absolute;
  /* Raised so the pen sits level with the social links. Kept short enough
     that its cap stays inside the footer, and started right of the copyright
     so the drawn line does not run through that text. */
  bottom: 14%;
  left: 58%;
  width: min(20rem, 26%);
  z-index: 0;
  opacity: 0.85;
  pointer-events: none;
}

@media (max-width: 47.99rem) {
  .colophon__decal { display: none; }
}

/* Sits above the decal. The decal comes later in the DOM, so without this the
   line would paint over the text rather than behind it. */
.colophon__grid {
  position: relative;
  z-index: 1;
  display: grid;
  gap: 1.75rem clamp(1.5rem, 4vw, 3rem);
  align-items: start;
}

@media (min-width: 48rem) {
  /* Equal side columns put the copyright at the true centre of the page.
     With auto side columns it drifted, because CONTACT and the link columns
     are different widths. */
  .colophon__grid { grid-template-columns: 1fr auto 1fr; align-items: end; }
  .colophon__legal { text-align: center; }
  .colophon__cols { justify-self: end; }
}

/* The two link columns share a top edge so their headings line up, while the
   row as a whole sits on the baseline with CONTACT and the copyright. */
.colophon__cols { display: flex; align-items: start; gap: clamp(1.5rem, 4vw, 3.5rem); }

.colophon h2 {
  font-family: var(--font-ui);
  font-size: var(--step-0);
  font-weight: 700;
  text-transform: uppercase;
  text-decoration: underline;
  text-underline-offset: 3px;
  margin-bottom: 0.5rem;
}

.colophon ul { list-style: none; display: grid; gap: 0.2rem; }
.colophon a { font-family: var(--font-ui); text-decoration: none; }
.colophon a:hover { text-decoration: underline; }

.colophon__contact {
  font-family: var(--font-ui);
  font-weight: 700;
  text-transform: uppercase;
  text-decoration: underline;
  text-underline-offset: 3px;
  align-self: end;
}

/* max-width:none overrides the global p measure cap, which otherwise stops
   this from centring in its grid cell. */
.colophon__legal {
  font-family: var(--font-ui);
  font-size: var(--step--1);
  color: var(--ink-soft);
  align-self: end;
  max-width: none;
}

/* --------------------------------------------------------------- print -- */

@media print {
  .masthead, .colophon, .hero__mark, .button { display: none; }
  .frame { border: none; }
  body { color: #000; }
}
