/* ============================================================
   BASE — reset, typography, layout primitives, nav, buttons,
   reveal system, footer.
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  /* ScrollSmoother owns anchor scrolling; native smooth fights it. */
  scroll-padding-top: 6rem;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  font-variation-settings: 'wdth' 100, 'wght' 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

body.is-locked { overflow: hidden; }

/* MOBILE SCROLL

   Two things a phone does by default that this page should not inherit.

   Chaining: a gesture that runs past the end of the page hands itself to
   whatever is behind it — the browser's pull-to-refresh at the top, the
   address bar's own rubber band at the bottom. On a page that turns like
   plates, that reads as the page half-answering.

   And the grey flash on tap. It is Android's way of saying a link was
   hit, and every link here already answers with its own colour or rule. */
html, body { overscroll-behavior-y: contain; }

@media (pointer: coarse) {
  a, button, [role="button"], summary, label {
    -webkit-tap-highlight-color: transparent;
  }
}

/* Paper texture — barely there, keeps large flat areas from
   reading as a flat screen. Static, never animated. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  opacity: 0.045;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

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

h1, h2, h3, h4, p, ul, ol, figure, blockquote { margin: 0; }
ul, ol { list-style: none; padding: 0; }

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

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

::selection { background: var(--reagent); color: var(--on-reagent); }

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

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 10000;
  background: var(--ink);
  color: var(--paper);
  padding: 0.75rem 1.25rem;
  font-family: var(--mono);
  font-size: var(--t-mono);
  letter-spacing: var(--tr-mono);
  text-transform: uppercase;
}
.skip-link:focus { left: 0; }

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

/* ------------------------------------------------------------
   LAYOUT
   ------------------------------------------------------------ */
.wrap {
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section {
  padding-block: var(--section);
  border-top: 1px solid var(--rule);
}

.section--dark {
  padding-block: var(--section);
  background: var(--void);
  color: var(--void-ink);
}

/* ------------------------------------------------------------
   TYPE ROLES
   ------------------------------------------------------------ */
.h-display {
  font-size: var(--t-h2);
  line-height: var(--lh-h2);
  letter-spacing: var(--tr-display);
  font-variation-settings: 'wdth' 104, 'wght' 500;
  /* pretty, not balance: balance evens the line lengths and leaves a
     heading in a narrow column of its own. Filling the measure and only
     rescuing the last line uses the width the section actually has. */
  text-wrap: pretty;
}

/* THE ARRIVAL MARK

   A heading changes voice on the word it lands on — sans into serif italic
   — and the period after that word is the reaction. Both halves are one
   rule here rather than repeated per section, because it is a system and
   not a trick: the italic only ever takes the noun the argument turns on,
   and this site turns on four of them — dirección, lab, método, idea.

   Headings that have no such word do not get it. "Think. Make. Launch."
   is three equal beats and italicising one would break the triad; "The
   Marketing Lab" is a name, not a sentence; "¿Qué estás haciendo?" arrives
   on a verb and ends on a question mark, and bending the rule once for it
   would turn the whole thing back into decoration.

   No motion on it. The playing is in where the mark lands, not in making
   it move — five identical animated periods would be exactly the scattered
   effect this is meant to replace. */
.h-display em {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  letter-spacing: -0.01em;
}

/* THE MARK ITSELF

   The period that follows an italic is not a period any more: it is one of
   the three primitives the monogram is built from — triangle, square,
   circle — and it changes shape as you go down the page, in the order the
   hero resolves them. The same three shapes that mean nothing on their own
   and turn into TML.

   The glyph stays in the markup so the sentence still copies and still
   reads correctly aloud; it is drawn transparent and clipped away, and the
   box in its place carries the shape. Sized in em, so it belongs to the
   line it ends rather than to a pixel value.

   Scoped to the display headings and the one line in "what". The dot in a
   credential row is a separator, not a mark, and keeps its own rule. */
.h-display .dot,
.hero__title .dot,
.hero__slogan .dot,
.what__is .dot {
  display: inline-block;
  width: 0.15em;
  height: 0.15em;
  margin-left: 0.05em;
  background: var(--reagent);
  color: transparent;
  overflow: hidden;
  vertical-align: baseline;
}

/* Triangle, square, circle, and round again — one step per mark, in
   reading order down the page. The shape is written on the mark itself
   rather than derived from the section it happens to live in, because the
   sequence is a sequence: four of them fall inside one headline, where a
   rule keyed to the section could only ever give all four the same face. */
.dot--tri { clip-path: polygon(50% 0%, 100% 100%, 0% 100%); }
.dot--sq  { border-radius: 0; }
.dot--cir { border-radius: 50%; }

.lead {
  font-size: var(--t-lead);
  line-height: 1.45;
  letter-spacing: -0.015em;
}

/* ------------------------------------------------------------
   BUTTONS & LINKS
   ------------------------------------------------------------ */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.9rem;
  padding: 1.05rem 1.6rem;
  font-family: var(--mono);
  font-size: var(--t-mono);
  font-weight: 500;
  letter-spacing: var(--tr-mono);
  text-transform: uppercase;
  line-height: 1;
  border: 1px solid transparent;
  transition: background var(--fast) var(--ease-in),
              color var(--fast) var(--ease-in),
              border-color var(--fast) var(--ease-in);
}

.btn--solid { background: var(--ink); color: var(--paper); }
.btn--solid:hover { background: var(--reagent); }

.btn--line { border-color: var(--rule); color: var(--ink); }
.btn--line:hover { border-color: var(--ink); background: var(--ink); color: var(--paper); }

.btn--ghost { padding: 0.6rem 0; color: inherit; }
.btn--ghost:hover { color: var(--reagent); }

.arrow {
  display: inline-block;
  transition: transform var(--fast) var(--ease);
}
.btn:hover .arrow { transform: translateX(0.35rem); }
.btn:hover .arrow--down { transform: translateY(0.3rem); }

/* ------------------------------------------------------------
   NAV
   ------------------------------------------------------------ */
.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  transition: transform var(--mid) var(--ease), background var(--fast) linear;
  /* iOS Safari despega el fixed del nav cuando hay un backdrop-filter
     encima del canvas WebGL del mundo: sin capa GPU propia, el nav
     "flota" en medio del contenido durante el scroll en vez de quedar
     pegado arriba. Forzar su propia capa de composición lo arregla. */
  transform: translateZ(0);
  -webkit-transform: translateZ(0);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.nav--hidden { transform: translateY(-100%); }
.nav--stuck {
  background: rgba(245, 245, 243, 0.84);
  background: color-mix(in srgb, var(--paper) 84%, transparent);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
}
.nav--light { color: var(--void-ink); }
.nav--light.nav--stuck {
  background: rgba(11, 11, 11, 0.76);
  background: color-mix(in srgb, var(--void) 76%, transparent);
}
/* la barra cubre el safe-area del notch/Dynamic Island para que nada asome arriba */
.nav { padding-top: env(safe-area-inset-top, 0px); }

.nav__inner {
  max-width: var(--max);
  margin-inline: auto;
  padding: 1.4rem var(--gutter);
  display: flex;
  align-items: center;
  gap: clamp(1rem, 4vw, 3.5rem);
}

.nav__mark {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin-right: auto;
}
.nav__mark-short {
  display: block;
  /* Matches the cap height of the mono wordmark beside it, so the two
     read as one lockup rather than as a logo next to some text. */
  width: 2.55rem;
  /* Reagent, like the hero figure and the footer: the monogram is the
     brand mark, not an accent, and it is the one thing on the page
     allowed to hold the colour without having reacted to anything.
     It inherited the page ink before, which made the bar's mark the
     only one of the three drawn in a different colour from the others. */
  color: var(--reagent);
}
.mark__svg { width: 100%; height: auto; display: block; overflow: visible; }
.mark__shape { fill: currentColor; }

.nav__mark-long {
  font-family: var(--mono);
  font-size: var(--t-mono);
  letter-spacing: var(--tr-mono);
  text-transform: uppercase;
  color: var(--ink-3);
  transition: color var(--fast) linear;
}
.nav--light .nav__mark-long { color: var(--void-ink-2); }

.nav__links {
  display: flex;
  gap: clamp(1rem, 2.4vw, 2.4rem);
  font-family: var(--mono);
  font-size: var(--t-mono);
  font-weight: 500;
  letter-spacing: var(--tr-mono);
  text-transform: uppercase;
}
.nav__links a {
  position: relative;
  padding-block: 0.4rem;
}
.nav__links a::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: var(--reagent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--fast) var(--ease);
}
.nav__links a:hover::after { transform: scaleX(1); }

.nav__toggle {
  display: none;
  align-items: center;
  gap: 0.6rem;
  background: none;
  border: 0;
  padding: 0.5rem 0;
  cursor: pointer;
  font-family: var(--mono);
  font-size: var(--t-mono);
  font-weight: 500;
  letter-spacing: var(--tr-mono);
  text-transform: uppercase;
}
.nav__toggle-bars { display: inline-flex; flex-direction: column; gap: 5px; width: 20px; }
.nav__toggle-bars i {
  display: block; height: 1px; background: currentColor;
  transition: transform var(--fast) var(--ease), opacity var(--fast) linear;
}
.nav__toggle[aria-expanded="true"] .nav__toggle-bars i:first-child { transform: translateY(3px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] .nav__toggle-bars i:last-child { transform: translateY(-3px) rotate(-45deg); }

/* ------------------------------------------------------------
   OVERLAY MENU
   ------------------------------------------------------------ */
.menu {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: var(--void);
  color: var(--void-ink);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 3rem;
  padding: 7rem var(--gutter) 3rem;
  opacity: 0;
  transition: opacity var(--fast) var(--ease-in);
}
.menu.is-open { opacity: 1; }

.menu__nav { display: flex; flex-direction: column; }
.menu__nav a {
  display: flex;
  align-items: baseline;
  gap: 1.2rem;
  padding-block: clamp(0.6rem, 2vh, 1.1rem);
  border-bottom: 1px solid var(--void-rule);
  font-size: clamp(2rem, 9vw, 3.25rem);
  line-height: 1;
  letter-spacing: -0.04em;
  font-variation-settings: 'wdth' 104, 'wght' 500;
  transition: color var(--fast) linear;
}
.menu__nav a:hover { color: var(--reagent); }
.menu__idx {
  font-family: var(--mono);
  font-size: var(--t-mono);
  letter-spacing: var(--tr-mono);
  color: var(--void-ink-2);
}

.menu__foot { display: flex; flex-direction: column; gap: 1.5rem; align-items: flex-start; }
.menu__foot .btn--solid { background: var(--paper); color: var(--ink); }
.menu__foot .btn--solid:hover { background: var(--reagent); color: var(--on-reagent); }
.menu__slogan {
  font-family: var(--mono);
  font-size: var(--t-mono);
  letter-spacing: var(--tr-mono);
  text-transform: uppercase;
  color: var(--void-ink-2);
}

/* ------------------------------------------------------------
   REVEAL SYSTEM
   Only active when JS runs — with JS off everything is visible.
   ------------------------------------------------------------ */
.js [data-reveal] {
  opacity: 0;
  transform: translate3d(0, 1.6rem, 0);
  transition: opacity var(--mid) var(--ease-in), transform var(--mid) var(--ease);
}
.js [data-reveal].is-visible { opacity: 1; transform: none; }

.line {
  display: block;
  overflow: hidden;
  /* Headroom for descenders inside the reveal clip. At line-height 0.86
     the "g" of "Marketing" pushes 0.032em past the box, so 0.08em was
     shearing it. Padding and negative margin are equal and opposite, so
     the layout does not shift. */
  padding-bottom: 0.16em;
  margin-bottom: -0.16em;
}
.js .line__in {
  display: block;
  transform: translate3d(0, 110%, 0);
  transition: transform var(--slow) var(--ease);
}
.js .is-visible .line__in { transform: none; }
.js .is-visible .line:nth-child(2) .line__in { transition-delay: 0.09s; }
.js .is-visible .line:nth-child(3) .line__in { transition-delay: 0.18s; }

/* ------------------------------------------------------------
   PIXEL LOADER
   A 3x3 grid of cells lit by a travelling wavefront, a shimmering
   label and an elapsed counter. Used while a request is in flight,
   which on this site means the enquiry form and nothing else.

   Three variants:
     default   square cells, chevron front driving right
     --dots    same front, round cells
     --orbit   a single cell lapping the perimeter

   The cycle is deliberately shorter than the sweep, so two fronts
   are in flight at once and the grid never reads as empty.

   Colour comes from two local custom properties rather than the
   page tokens directly, because the form this serves sits on the
   dark section and the component has to survive both grounds.
   Reduced motion is handled globally in tokens.css: the animation
   stops and the grid rests at its dim state, while the counter,
   which is the part that actually carries information, keeps
   running.
   ------------------------------------------------------------ */
.loader {
  --loader-ink: var(--ink);
  --loader-ink-2: var(--ink-2);
  --loader-dur: 650ms;
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
}
.section--dark .loader {
  --loader-ink: var(--void-ink);
  --loader-ink-2: var(--void-ink-2);
}

.loader__grid {
  display: grid;
  grid-template-columns: repeat(3, 4px);
  gap: 1.5px;
}
.loader__cell {
  width: 4px;
  height: 4px;
  border-radius: 1px;
  background: var(--loader-ink);
  opacity: 0.15;
  animation: pixel-on var(--loader-dur) ease-in-out var(--loader-delay, 0ms) infinite;
}
.loader--dots .loader__cell { border-radius: 50%; }

.loader--orbit { --loader-dur: 950ms; }
/* The five cells the comet never reaches sit lower than the others
   so the ring reads as a path and not as a broken grid. */
.loader__cell--off { opacity: 0.07; animation: none; }

/* The label keeps the mono, uppercase, tracked setting every other
   micro-label on this site uses. The shimmer is the borrowed part;
   the typeface is ours. */
.loader__label {
  font-family: var(--mono);
  font-size: var(--t-mono);
  letter-spacing: var(--tr-mono);
  text-transform: uppercase;
  background-image: linear-gradient(90deg,
    var(--loader-ink-2) 35%, var(--loader-ink) 50%, var(--loader-ink-2) 65%);
  background-size: 200% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: shimmer-text 1.4s linear infinite;
}
/* Without the animation the gradient parks off-screen and the label
   disappears. Reduced motion gets flat ink instead. */
@media (prefers-reduced-motion: reduce) {
  .loader__label { background-image: none; color: var(--loader-ink); }

}

/* Tabular figures, so the counter does not jitter as digits change. */
.loader__time {
  font-family: var(--mono);
  font-size: var(--t-mono);
  letter-spacing: var(--tr-mono);
  color: var(--loader-ink-2);
  font-variant-numeric: tabular-nums;
  transition: opacity var(--fast) var(--ease);
}
.loader__time[hidden] { display: none; }

@keyframes pixel-on {
  0%, 100% { opacity: 0.12; }
  50%      { opacity: 1; }

}
@keyframes shimmer-text {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }

}

/* ------------------------------------------------------------
   FOOTER
   ------------------------------------------------------------ */
.foot {
  border-top: 1px solid var(--rule);
  padding-block: clamp(3rem, 7vw, 5rem);
  font-family: var(--mono);
  font-size: var(--t-mono);
  letter-spacing: var(--tr-mono);
  text-transform: uppercase;
  color: var(--ink-2);
}
.foot__inner {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}
.foot__mark {
  /* Sized so the cap height matches what the lettered version had.
     The box is 458.9 wide and the letters occupy 404.3 of it, so the
     width is scaled up by 1/0.881 to keep the ink the same size as
     the type it replaced -- clamp(3rem, 9vw, 7rem) at cap height. */
  width: clamp(7.26rem, 21.6vw, 16.75rem);
  color: var(--reagent);
  cursor: pointer;
}
.foot__name { margin-top: 1rem; }
.foot__nav { display: flex; flex-direction: column; gap: 0.6rem; }

/* Touch. These links are set at the label size, so each one is about 18px
   tall -- a fine target for a cursor and a poor one for a thumb. Where the
   pointer is coarse the gap moves inside the link as padding: the rhythm
   on screen is unchanged, the rows still do not touch each other, and each
   one grows to a real target. */
@media (pointer: coarse) {
  .foot__nav, .foot__contact { gap: 0; }
  .foot__nav a, .foot__contact > a { padding-block: 0.8rem; }
}
.foot__nav a:hover, .foot__contact a:hover { color: var(--reagent-deep); }
.foot__contact { display: flex; flex-direction: column; gap: 0.6rem; }
.foot__social { display: flex; gap: 1.2rem; margin-top: 0.6rem; color: var(--ink-3); }
.foot__legal {
  grid-column: 1 / -1;
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding-top: clamp(2rem, 5vw, 3.5rem);
  border-top: 1px solid var(--rule);
  color: var(--ink-3);
}

@media (max-width: 900px) {
  .nav__links, .nav__cta { display: none; }
  .nav__toggle { display: inline-flex; }
  .foot__inner { grid-template-columns: 1fr; }

}

@media (min-width: 901px) {
  .menu { display: none; }

}

/* Intro veil — sits above everything, including the paper texture (9999)
   and the skip link (10000). Never interactive: it is scenery, and it is
   removed from the DOM the moment it finishes. */
.veil {
  /* Hidden by default, shown only once a script has confirmed it can take
     it away again. The veil's only exit is JavaScript, so if scripts are
     off, blocked or broken, an always-visible veil would cover the page
     permanently. Same rule as the reveals: nothing hides content until
     something can bring it back. */
  display: none;
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 10001;
  pointer-events: none;
}
.js .veil { display: block; }

@media (prefers-reduced-motion: reduce) {
  .js .veil { display: none; }

}

/* Language switch. Two states of one control, so it is set like every
   other label in the system: mono, uppercase, and the active side simply
   carries more ink than the other. */
.lang {
  /* Hidden without scripts: the switch is JS-driven, and a dead control
     is worse than no control. Same rule as the veil. */
  display: none;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--mono);
  font-size: var(--t-mono);
  font-weight: 500;
  letter-spacing: var(--tr-mono);
}
.js .lang { display: flex; }

.lang__b {
  background: none;
  border: 0;
  padding: 0.4rem 0;
  color: var(--ink-3);
  font: inherit;
  letter-spacing: inherit;
  text-transform: uppercase;
  cursor: pointer;
  transition: color var(--fast) var(--ease-in);
}
.lang__b.is-on { color: var(--ink); }
.lang__b:hover { color: var(--reagent); }
/* Same reason as the form's error line: on the void the plain accent is
   4.30:1, and this control is set at the label size. */
.nav--light .lang__b:hover { color: var(--reagent-lift); }
.lang__sep { color: var(--rule); }

.nav--light .lang__b { color: var(--void-ink-2); }
.nav--light .lang__b.is-on { color: var(--void-ink); }
.nav--light .lang__sep { color: var(--void-rule); }

.lang--menu { margin-top: 1.6rem; color: var(--void-ink-2); }
.lang--menu .lang__b { color: var(--void-ink-2); }
.lang--menu .lang__b.is-on { color: var(--void-ink); }

@media (max-width: 859px) {
  .nav .lang { display: none; }   /* the overlay menu carries it below this width */

}

/* ------------------------------------------------------------
   LINE BREAKING
   A single word alone on the last line reads as a mistake, and it
   happens to every short sentence sitting in a max-width measure.
   `pretty` only reflows the last couple of lines, so paragraphs keep
   their shape; `balance` is reserved for the short display statements
   where even line lengths are the composition.
   ------------------------------------------------------------ */
p, li, dd, figcaption { text-wrap: pretty; }


/* ============================================================
   THE POINTER

   The arrow everyone knows, drawn as a 1px outline — the same
   hairline every edge and rule on this page is drawn with. See
   assets/js/cursor.js for why it is hollow at rest, why it blends,
   why it leans into movement, and why it steps aside over a text
   field.

   Nothing here applies until the script confirms a mouse that is
   actually moving: .has-cursor is what hides the native arrow, so
   a page with the script blocked, a touchscreen, or someone who
   asked for less motion keeps the ordinary one.
   ============================================================ */
.cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 10050;
  width: 20px;
  height: 24px;
  pointer-events: none;
  opacity: 0;
  /* The tip is the hotspot, so every transform pivots on it. */
  transform-origin: 0 0;
  /* Legible on paper and on void without being told which it is on:
     difference against white lands near-black over one and near-white
     over the other, and cannot be caught out mid-transition. */
  mix-blend-mode: difference;
  transition: opacity 0.25s var(--ease);
}

.cursor.is-awake { opacity: 1; }
.cursor.is-hidden { opacity: 0; }

.cursor__svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  transition: transform 0.18s var(--ease);
}

/* Hollow at rest. The stroke is white because of the blend above, which
   inverts it against whichever ground it happens to be over. */
.cursor__arrow {
  fill: none;
  stroke: #fff;
  stroke-width: 1;
  stroke-linejoin: round;
  transition: fill 0.18s var(--ease), stroke 0.18s var(--ease);
}

/* Over something that can actually be done: the arrow fills. The blend
   comes off with it, so the accent is the real accent and not whatever
   difference would make of it. Solid for active, hollow for resting —
   the oldest convention there is, and the page's own rule about the
   accent being a reaction, in one gesture. */
.cursor.is-hot {
  mix-blend-mode: normal;
}

.cursor.is-hot .cursor__arrow {
  fill: var(--reagent);
  stroke: var(--reagent);
}

.cursor.is-hot .cursor__svg { transform: scale(1.14); }

/* Pressed: a small give, not a collapse — and the arrow takes the
   reagent while the button is down, wherever it is: press = reaction. */
.cursor.is-down .cursor__svg { transform: scale(0.9); }
.cursor.is-hot.is-down .cursor__svg { transform: scale(1.02); }
.cursor.is-down { mix-blend-mode: normal; }
.cursor.is-down .cursor__arrow {
  fill: var(--reagent);
  stroke: var(--reagent);
}

/* The native pointer goes only once there is something to replace it
   with, and comes back over anything with a caret. */
.has-cursor,
.has-cursor * { cursor: none; }

.has-cursor.cursor-native,
.has-cursor.cursor-native * { cursor: auto; }

@media (pointer: coarse) {
  .cursor { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .cursor { display: none; }
  .has-cursor, .has-cursor * { cursor: auto; }
}
