/* ==========================================================================
   Dreidrone site styles.

   Blue is drawn from the cyanotype process, which was invented to reproduce
   technical drawings and is the colour of survey documents and charts. The
   company does not sell flying, it turns a place into a document, so the page
   is built as sheets laid over aerial photographs, and the reveal prints the
   photograph as a cyanotype.

   Text is deep Prussian rather than black, which is what makes the page cohere.

   Contrast constraints, measured rather than assumed:
     ink on paper 13.37:1, ink on sheet 14.63:1, paper on ink 13.37:1.
     slate on paper 5.73:1. slate is barred from text on ink (2.71:1).
     cyan on paper 4.65:1, so it may carry text on light ground.
     sheet on cyan 5.08:1, so button labels are sheet. ink on cyan is 2.88:1.
     cyan on ink is 2.88:1, below even the 3:1 non-text floor, so nothing cyan
       appears on the ink band. cyan-light (5.73:1) covers every use there.
   ========================================================================== */

@layer tokens, base, layout, components, utilities;

/* --------------------------------------------------------------------------
   Tokens
   -------------------------------------------------------------------------- */
@layer tokens {
  :root {
    --paper: #EDF1F4;
    --sheet: #F9FBFC;
    --ink: #0E2740;
    --slate: #4A6076;
    --slate-light: #93A9BC;
    --cyan: #0B6FB8;
    --cyan-deep: #075A96;
    --cyan-light: #4FA6E6;

    --rule: rgba(74, 96, 118, 0.26);
    --rule-on-ink: rgba(147, 169, 188, 0.28);

    --display: 'Familjen Grotesk', 'Segoe UI', system-ui, sans-serif;
    --body: 'Barlow', 'Segoe UI', system-ui, sans-serif;

    /* Capped so "from above." stays on one line inside the sheet. Larger and
       it strands "from" on a line of its own. */
    --step-display: clamp(3rem, 6.4vw, 5.5rem);
    --step-h2: clamp(2.25rem, 5vw, 4rem);
    --step-h3: clamp(1.75rem, 3.5vw, 2.75rem);
    --step-lede: clamp(1.125rem, 1.6vw, 1.375rem);
    --step-body: 1.0625rem;
    --step-small: 0.9375rem;
    --step-label: 0.75rem;

    --space-1: 0.25rem;
    --space-2: 0.5rem;
    --space-3: 0.75rem;
    --space-4: 1rem;
    --space-6: 1.5rem;
    --space-8: 2rem;
    --space-12: 3rem;
    --space-16: 4rem;
    --space-24: 6rem;
    --space-32: 8rem;

    --gutter: clamp(1.25rem, 5vw, 4.5rem);
    --measure-lede: 52ch;
    --measure-body: 62ch;
    --section-pad: clamp(5rem, 12vh, 10rem);
    --container: 1440px;

    /* Where the cyanotype edge settles. The hero overrides this so the edge
       lands exactly where the sheet ends. */
    --pass-at: 55%;

    --ease: cubic-bezier(0.22, 1, 0.36, 1);
  }
}

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */
@layer base {
  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }

  html {
    scroll-behavior: smooth;
  }

  body {
    margin: 0;
    background: var(--paper);
    color: var(--ink);
    font-family: var(--body);
    font-size: var(--step-body);
    line-height: 1.65;
    -webkit-font-smoothing: antialiased;
    overflow-x: clip;
  }

  h1, h2, h3, h4 {
    margin: 0;
    font-family: var(--display);
    font-weight: 600;
    line-height: 1.05;
    letter-spacing: -0.025em;
    text-wrap: balance;
  }

  p {
    margin: 0;
    text-wrap: pretty;
  }

  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  a {
    color: inherit;
    text-decoration: none;
  }

  img,
  picture,
  svg {
    display: block;
    max-width: 100%;
  }

  button,
  input,
  select,
  textarea {
    font: inherit;
    color: inherit;
  }

  ::selection {
    background: var(--cyan);
    color: var(--sheet);
  }

  :focus-visible {
    outline: 3px solid var(--cyan);
    outline-offset: 3px;
    border-radius: 1px;
  }
}

/* --------------------------------------------------------------------------
   Layout
   -------------------------------------------------------------------------- */
@layer layout {
  .container {
    width: 100%;
    max-width: var(--container);
    margin-inline: auto;
    padding-inline: var(--gutter);
  }

  .section {
    padding-block: var(--section-pad);
  }

  .band--ink {
    background: var(--ink);
    color: var(--paper);
  }

  .band--ink .lede {
    color: var(--slate-light);
  }
}

/* --------------------------------------------------------------------------
   Components
   -------------------------------------------------------------------------- */
@layer components {

  /* Shared type ---------------------------------------------------------- */
  .eyebrow {
    margin-bottom: var(--space-6);
    font-family: var(--display);
    font-size: var(--step-label);
    font-weight: 600;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    line-height: 1.2;
    color: var(--cyan-deep);
  }

  .eyebrow--light {
    color: var(--cyan-light);
  }

  .section__heading {
    font-size: var(--step-h2);
    max-width: 20ch;
  }

  .section__heading + .lede {
    margin-top: var(--space-6);
  }

  .lede {
    max-width: var(--measure-lede);
    font-size: var(--step-lede);
    line-height: 1.55;
    color: var(--slate);
  }

  /* Registration tick, borrowed from the corner of a drawing sheet. Used on
     the hero sheet and, at small size, to mark list items. */
  .tick {
    position: absolute;
    width: 14px;
    height: 14px;
    border: 0 solid var(--cyan);
  }

  /* Buttons -------------------------------------------------------------- */
  .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: 0.9em 1.7em;
    border: 1px solid transparent;
    border-radius: 1px;
    font-family: var(--display);
    font-size: var(--step-small);
    font-weight: 600;
    letter-spacing: 0.02em;
    cursor: pointer;
    transition: background-color 200ms var(--ease), border-color 200ms var(--ease), color 200ms var(--ease);
  }

  /* Label is sheet, not ink: ink on cyan measures 2.88:1 and fails. */
  .btn--primary {
    background: var(--cyan);
    color: var(--sheet);
  }

  .btn--primary:hover {
    background: var(--ink);
  }

  .btn--ghost {
    border-color: var(--slate);
    color: var(--ink);
  }

  .btn--ghost:hover {
    border-color: var(--ink);
    background: rgba(14, 39, 64, 0.05);
  }

  .btn--small {
    padding: 0.7em 1.25em;
  }

  .btn--block {
    width: 100%;
  }

  /* Header --------------------------------------------------------------- */
  .site-header {
    position: relative;
    z-index: 20;
    background: var(--paper);
    border-bottom: 1px solid var(--rule);
  }

  .site-header__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-6);
    min-height: 72px;
  }

  .brand {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    color: var(--ink);
  }

  .brand__mark {
    width: 28px;
    height: 28px;
    color: var(--cyan);
  }

  .brand__name {
    font-family: var(--display);
    font-size: 1.15rem;
    font-weight: 700;
    letter-spacing: -0.02em;
  }

  .nav {
    display: flex;
    align-items: center;
    gap: var(--space-8);
    font-family: var(--display);
    font-size: var(--step-small);
    font-weight: 500;
  }

  .nav a:not(.btn):hover {
    color: var(--cyan-deep);
  }

  .nav-toggle {
    display: none;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    background: none;
    border: 1px solid var(--rule);
    border-radius: 1px;
    cursor: pointer;
  }

  .nav-toggle__bars {
    display: grid;
    gap: 5px;
    width: 18px;
  }

  .nav-toggle__bars span {
    display: block;
    height: 2px;
    background: var(--ink);
  }

  /* The pass: the photograph printed as a cyanotype ---------------------- */
  .pass {
    position: relative;
    margin: 0;
    overflow: hidden;
    background: var(--ink);
  }

  .pass__base,
  .pass__zoom {
    position: absolute;
    inset: 0;
  }

  .pass__base picture,
  .pass__zoom picture {
    display: block;
    height: 100%;
  }

  .pass__base img,
  .pass__zoom img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  .pass__zoom {
    clip-path: inset(0 0 0 100%);
    transition: clip-path 1200ms var(--ease);
  }

  /* The cyanotype itself. If the SVG filter is unsupported the image simply
     renders untreated, which degrades quietly. */
  .pass__zoom img {
    filter: url(#cyanotype);
    transform: scale(1.15);
    transform-origin: var(--pass-origin, center);
  }

  .pass__edge {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 100%;
    width: 2px;
    background: var(--cyan-light);
    transition: left 1200ms var(--ease);
  }

  .pass.is-revealed .pass__zoom {
    clip-path: inset(0 0 0 var(--pass-at));
  }

  .pass.is-revealed .pass__edge {
    left: var(--pass-at);
  }

  /* Hero: a sheet laid over the place ------------------------------------ */
  .hero {
    --pass-at: 46%;
    position: relative;
    display: grid;
    align-items: center;
    min-height: min(90vh, 880px);
    isolation: isolate;
  }

  .hero__figure {
    position: absolute;
    inset: 0;
    z-index: -1;
  }

  .hero__sheet {
    position: relative;
    width: min(46%, 46rem);
    /* Generous margin above and below, so the photograph showing past the
       sheet reads as deliberate rather than as a gap. */
    margin-block: clamp(3rem, 9vh, 7rem);
    padding: clamp(2.5rem, 5vw, 4rem) clamp(2rem, 4vw, 3.5rem) clamp(2.5rem, 5vw, 4rem) var(--gutter);
    background: var(--sheet);
    border-right: 2px solid var(--cyan);
  }

  /* Two registration ticks on the exposed corners. The only decoration on
     the page, and it says the sheet is a drawing of the site behind it. */
  .hero__sheet .tick {
    inset-inline-end: 14px;
  }

  .hero__sheet .tick--top {
    top: 14px;
    border-top-width: 2px;
    border-right-width: 2px;
  }

  .hero__sheet .tick--bottom {
    bottom: 14px;
    border-bottom-width: 2px;
    border-right-width: 2px;
  }

  .hero__heading {
    font-size: var(--step-display);
    font-weight: 700;
    letter-spacing: -0.035em;
    line-height: 0.9;
    max-width: 12ch;
  }

  .hero__lede {
    margin-top: var(--space-6);
  }

  .hero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
    margin-top: var(--space-8);
  }

  /* Services ------------------------------------------------------------- */
  .services {
    display: grid;
    gap: clamp(4rem, 9vw, 8rem);
    margin-top: clamp(3rem, 7vw, 6rem);
  }

  .service {
    display: grid;
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    align-items: center;
    gap: clamp(2rem, 5vw, 5rem);
  }

  .service__figure {
    aspect-ratio: 16 / 9;
  }

  .service__body {
    max-width: 46ch;
    padding-inline-end: var(--gutter);
  }

  /* The order swap alone would leave the figure in the narrow column, so the
     track widths are reversed to match. */
  .service--flip {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr);
  }

  .service--flip .service__figure {
    order: 2;
  }

  .service--flip .service__body {
    order: 1;
    justify-self: end;
    padding-inline: var(--gutter) 0;
  }

  .service__title {
    font-size: var(--step-h3);
    margin-bottom: var(--space-4);
  }

  .service__body p {
    color: var(--slate);
  }

  .service__list {
    margin-top: var(--space-8);
    display: grid;
    gap: var(--space-4);
    font-size: var(--step-small);
    font-weight: 500;
  }

  /* A small registration tick rather than a rule per row. Rules on every item
     turn the section into a table, which is not what a list of capabilities is. */
  .service__list li {
    display: grid;
    grid-template-columns: 1.1rem 1fr;
    align-items: start;
    gap: var(--space-3);
  }

  .service__list li::before {
    content: '';
    width: 9px;
    height: 9px;
    margin-top: 0.45em;
    border-left: 2px solid var(--cyan);
    border-bottom: 2px solid var(--cyan);
  }

  @media (min-width: 1100px) {
    .service:not(.service--flip) .service__title {
      transform: translateX(calc(var(--space-8) * -1));
    }

    .service--flip .service__title {
      transform: translateX(var(--space-8));
    }
  }

  /* About ---------------------------------------------------------------- */
  .about {
    display: grid;
    gap: clamp(3rem, 7vw, 6rem);
  }

  .points {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(2rem, 5vw, 4.5rem);
  }

  .point {
    padding-top: var(--space-6);
    border-top: 1px solid var(--rule-on-ink);
  }

  .point__title {
    font-size: 1.35rem;
    margin-bottom: var(--space-3);
  }

  .point p {
    color: var(--slate-light);
  }

  /* Contact -------------------------------------------------------------- */
  .contact {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr);
    gap: clamp(3rem, 7vw, 6rem);
    align-items: start;
  }

  .contact__details {
    margin: var(--space-12) 0 0;
    display: grid;
    gap: var(--space-4);
  }

  .contact__row {
    display: grid;
    grid-template-columns: 7.5rem 1fr;
    gap: var(--space-4);
    padding-top: var(--space-4);
    border-top: 1px solid var(--rule);
  }

  .contact__row dt {
    font-family: var(--display);
    font-size: var(--step-label);
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--slate);
    padding-top: 0.35em;
  }

  .contact__row dd {
    margin: 0;
  }

  .contact__row a {
    color: var(--cyan-deep);
  }

  .contact__row a:hover {
    color: var(--ink);
  }

  /* Form ----------------------------------------------------------------- */
  .form {
    display: grid;
    gap: var(--space-4);
    padding: clamp(1.5rem, 3vw, 2.5rem);
    background: var(--sheet);
    border: 1px solid var(--rule);
    border-top: 2px solid var(--cyan);
    border-radius: 1px;
  }

  .field {
    display: grid;
    gap: var(--space-2);
  }

  .field label {
    font-family: var(--display);
    font-size: var(--step-label);
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--slate);
  }

  .field input,
  .field select,
  .field textarea {
    width: 100%;
    padding: 0.7em 0.85em;
    background: var(--paper);
    border: 1px solid var(--rule);
    border-radius: 1px;
    transition: border-color 160ms var(--ease);
  }

  .field textarea {
    resize: vertical;
    min-height: 7rem;
  }

  .field input:hover,
  .field select:hover,
  .field textarea:hover {
    border-color: var(--slate);
  }

  .field [aria-invalid='true'] {
    border-color: var(--cyan-deep);
    border-width: 2px;
  }

  .field__error {
    font-size: var(--step-small);
    font-weight: 500;
    color: var(--cyan-deep);
  }

  .form-status {
    margin-top: var(--space-1);
    min-height: 1.5em;
    font-size: var(--step-small);
    font-weight: 500;
    color: var(--slate);
  }

  .form-status[data-state='error'] {
    color: var(--cyan-deep);
  }

  .form-status[data-state='success'] {
    color: var(--ink);
  }

  .btn[disabled] {
    opacity: 0.65;
    cursor: progress;
  }

  /* Honeypot. Positioned off-screen rather than display:none, because some
     bots skip fields that are display:none. */
  .hp {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
  }

  /* Footer --------------------------------------------------------------- */
  .site-footer {
    background: var(--ink);
    color: var(--paper);
    padding-block: var(--space-12);
  }

  .site-footer__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-6);
  }

  .site-footer .brand {
    color: var(--paper);
  }

  .site-footer .brand__mark {
    color: var(--cyan-light);
  }

  .site-footer__links {
    display: flex;
    gap: var(--space-6);
    font-family: var(--display);
    font-size: var(--step-small);
    font-weight: 500;
  }

  .site-footer__links a:hover {
    color: var(--cyan-light);
  }

  .site-footer__note {
    font-size: var(--step-small);
    color: var(--slate-light);
  }

  /* Editor content, used by the page and post templates only -------------- */
  .page-entry__content {
    max-width: var(--measure-body);
    margin-top: var(--space-8);
  }

  .page-entry__content > * + * {
    margin-top: var(--space-6);
  }

  .page-entry__content h2 {
    font-size: 1.9rem;
    margin-top: var(--space-12);
  }

  .page-entry__content h3 {
    font-size: 1.4rem;
    margin-top: var(--space-8);
  }

  .page-entry__content a {
    color: var(--cyan-deep);
    text-decoration: underline;
    text-underline-offset: 0.2em;
  }

  .page-entry__content ul {
    list-style: disc;
    padding-left: 1.25em;
  }

  .page-entry__content li + li {
    margin-top: var(--space-2);
  }
}

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

  /* Holds the cyanotype filter definition. Zero size, never rendered. */
  .u-svg-defs {
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
  }

  .u-stack-top {
    margin-top: var(--space-8);
  }

  .skip-link {
    position: absolute;
    top: var(--space-2);
    left: var(--space-2);
    z-index: 100;
    padding: 0.75em 1.25em;
    background: var(--cyan);
    color: var(--sheet);
    font-family: var(--display);
    font-weight: 600;
    border-radius: 1px;
    transform: translateY(-200%);
  }

  .skip-link:focus {
    transform: translateY(0);
  }
}

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */
@media (max-width: 900px) {
  .nav-toggle {
    display: inline-flex;
  }

  .nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-2);
    padding: var(--space-4) var(--gutter) var(--space-6);
    background: var(--paper);
    border-bottom: 1px solid var(--rule);
  }

  .nav.is-open {
    display: flex;
  }

  .hero {
    --pass-at: 55%;
    align-items: end;
    min-height: min(88vh, 760px);
  }

  .hero__sheet {
    width: 100%;
    padding-inline: var(--gutter);
    border-right: 0;
    border-top: 2px solid var(--cyan);
  }

  .hero__sheet .tick {
    display: none;
  }

  .service,
  .contact,
  .points {
    grid-template-columns: minmax(0, 1fr);
  }

  .service--flip .service__figure,
  .service--flip .service__body {
    order: initial;
  }

  .service__body,
  .service--flip .service__body {
    padding-inline: var(--gutter);
    justify-self: stretch;
    max-width: none;
  }

  .service__title,
  .service--flip .service__title {
    transform: none;
  }
}

@media (max-width: 560px) {
  .contact__row {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-1);
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  .pass__zoom,
  .pass__edge {
    transition: none;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}
