/* Hidloo — the whole look of hidloo.app, in one file.
 *
 * **Shared on purpose, after being duplicated once.** The English and Spanish
 * landing pages carried identical inline stylesheets, which meant every visual
 * fix had to be made twice and stayed correct only as long as somebody
 * remembered. Two copies of a stylesheet are two stylesheets that will
 * eventually disagree.
 *
 * Colours are the same hex values as lib/app_colors.dart. There is still no
 * shared source between a Flutter app and a static site, so that pairing is
 * kept by hand — but at least it is now kept in one place instead of two.
 */

:root {
  --bg:#1E2A78; --raised:#2C3A96; --deep:#141C54; --subtitle:#B9C2EE;
  --action:#CE4B07; --action-dark:#A03B06;
  --highlight:#F5A524; --success:#0B7D57;
}

* { box-sizing:border-box; }

body {
  margin:0; background:var(--bg); color:#fff;
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  line-height:1.6; -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

/* `height:auto` is not decoration — without it the browser honours the height
   attribute on the tag while max-width shrinks the width, and every screenshot
   renders stretched. */
img { max-width:100%; height:auto; display:block; }

.wrap { max-width:1000px; margin:0 auto; padding:0 24px; position:relative; z-index:1; }

/* ------------------------------------------------------------------ *
 *  The living background
 *
 *  Four layers, all fixed behind the page and all ignoring the pointer.
 *
 *  **Every colour here is from the app's own palette.** The first version
 *  reached for a violet to add interest and it read exactly as what it was —
 *  a stain from another brand parked in the corner. Depth in a single-hue
 *  background comes from value, not from borrowing a second hue, so the blobs
 *  are now three weights of the same indigo.
 *
 *  Only transform and opacity are animated — the two properties a browser can
 *  handle on the compositor without repainting — so a page full of motion
 *  still scrolls at full speed on a phone.
 * ------------------------------------------------------------------ */
.bg {
  position:fixed; inset:0; z-index:0; overflow:hidden;
  pointer-events:none; background:var(--bg);
}
.blob {
  position:absolute; border-radius:50%; filter:blur(110px); opacity:0.55;
  will-change:transform;
}
.blob.a { width:56vw; height:56vw; left:-18vw; top:-14vw;
  background:#2E3E9E; animation:drift1 38s ease-in-out infinite; }
.blob.b { width:48vw; height:48vw; right:-16vw; top:26vh;
  background:#16205E; animation:drift2 46s ease-in-out infinite; }
.blob.c { width:42vw; height:42vw; left:22vw; bottom:-18vw;
  background:#25348C; animation:drift3 52s ease-in-out infinite; }

@keyframes drift1 {
  0%,100% { transform:translate3d(0,0,0) scale(1); }
  50%     { transform:translate3d(5vw,3vh,0) scale(1.1); }
}
@keyframes drift2 {
  0%,100% { transform:translate3d(0,0,0) scale(1.05); }
  50%     { transform:translate3d(-4vw,-5vh,0) scale(1); }
}
@keyframes drift3 {
  0%,100% { transform:translate3d(0,0,0) scale(1); }
  50%     { transform:translate3d(3vw,-4vh,0) scale(1.12); }
}

/* Dashed graph paper.
 *
 * An SVG tile rather than stacked CSS gradients, because a dash needs a gap
 * *along* the line and a gradient can only repeat across one axis — faking it
 * takes four layers and still looks like a dotted grid rather than a broken
 * rule. Sixty pixels of tile, six on and eight off, at six percent white: at
 * that weight it is felt rather than seen, which is the whole job of a
 * texture. Any heavier and it competes with the screenshots. */
.grid {
  position:absolute; inset:-60px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='60' height='60'%3E%3Cg stroke='%23ffffff' stroke-opacity='0.06' stroke-width='1' stroke-dasharray='6 8'%3E%3Cpath d='M0 .5H60'/%3E%3Cpath d='M.5 0V60'/%3E%3C/g%3E%3C/svg%3E");
  animation:slide 90s linear infinite;
}
@keyframes slide {
  from { transform:translate3d(0,0,0); }
  to   { transform:translate3d(60px,60px,0); }
}

/* The edges, brought back under control.
 *
 * Two overlays in one element: a radial that sinks the corners, and a linear
 * that fades both sides. Without them the blobs run off the viewport with a
 * hard boundary and the page reads as a photograph that was cropped badly.
 * With them the colour has somewhere to go. */
.vignette {
  position:absolute; inset:0;
  background:
    radial-gradient(125% 95% at 50% 38%,
      rgba(10,15,50,0) 42%, rgba(10,15,50,0.62) 100%),
    linear-gradient(90deg,
      rgba(10,15,50,0.55) 0%, rgba(10,15,50,0) 16%,
      rgba(10,15,50,0) 84%, rgba(10,15,50,0.55) 100%);
}

/* The figures: the game, adrift in its own background.
 *
 * Outlines rather than fills, so they read as *hidden* rather than as
 * decoration — and much fainter than the first attempt, which put solid
 * shapes across the headline and pulled the eye off the one sentence that
 * has to be read. */
/* The drifting figures.
 *
 * **These used to be outlined squares** — a nice texture that told a visitor
 * nothing. They are now the real artwork from the app, so the first thing
 * anybody sees is a sample of what there is to hide.
 *
 * They live in `.bg`, which is fixed to the viewport, so all sixteen are on
 * screen at once and they drift past whatever is being read. A version that
 * confined them to one section looked right in the markup and wrong on the
 * page: that section is tall, so three landed above the fold and thirteen
 * ended up behind the phone screenshots.
 *
 * Opacity is low and deliberately so. This is the background of a page whose
 * job is to be read; the moment a bee competes with a headline it has stopped
 * being texture. The vignette painted over them does the rest, dimming the
 * ones near the edges so the field reads as depth.
 */
.figs { position:absolute; inset:0; }
.fig {
  position:absolute; opacity:0.14; will-change:transform;
  animation:drift var(--dur, 26s) ease-in-out infinite;
}
.fig img { width:100%; height:100%; display:block; object-fit:contain; }
/* Small screens get fewer pixels and the same amount of text, so the figures
   shrink rather than crowd it. */
@media (max-width:640px) {
  .fig { opacity:0.11; transform:scale(0.7); }
}
/* Each figure carries its own direction in --dx / --dy, so sixteen of them
   wander rather than sliding in formation. One shared pair of offsets was
   the first attempt and it read as a single sheet moving behind the page. */
@keyframes drift {
  0%   { transform:translate3d(0,0,0) rotate(calc(var(--rot, 8deg) * -1)); }
  50%  { transform:translate3d(var(--dx, 2vw), var(--dy, -3vh), 0)
                   rotate(var(--rot, 8deg)); }
  100% { transform:translate3d(0,0,0) rotate(calc(var(--rot, 8deg) * -1)); }
}

/* Motion is a flourish, never the message. Anybody who has asked their system
   to stop animating gets the same page, still. */
@media (prefers-reduced-motion: reduce) {
  .blob, .fig, .grid { animation:none !important; }
  .fig { opacity:0.10; animation:none; }
  .reveal { opacity:1 !important; transform:none !important; }
}

/* ------------------------------------------------------------------ *
 *  Navigation
 * ------------------------------------------------------------------ */
.nav {
  display:flex; align-items:center; justify-content:space-between;
  gap:14px; padding:18px 0; flex-wrap:wrap;
}
.brand {
  display:flex; align-items:center; gap:9px;
  font-weight:700; font-size:18px; color:#fff; text-decoration:none;
}
.brand svg { width:30px; height:30px; display:block; }
.links { display:flex; gap:4px; flex-wrap:wrap; align-items:center; }
.links a {
  color:var(--subtitle); text-decoration:none; font-size:14px;
  padding:7px 12px; border-radius:20px; white-space:nowrap;
  transition:background .18s, color .18s;
}
.links a:hover { color:#fff; background:rgba(255,255,255,0.10); }
.links a[aria-current="page"] { color:#fff; background:rgba(255,255,255,0.16); }
.lang {
  border:1px solid rgba(255,255,255,0.28); font-weight:600;
  font-size:13px; letter-spacing:0.3px;
}

/* ------------------------------------------------------------------ *
 *  Hero
 * ------------------------------------------------------------------ */
.hero { text-align:center; padding:44px 0 4px; }
.hero svg.mark { width:96px; height:96px; margin:0 auto 20px; display:block; }
h1 { font-size:46px; line-height:1.06; margin:0 0 16px; letter-spacing:-0.8px; }
.lead {
  color:var(--subtitle); font-size:19px; max-width:520px;
  margin:0 auto 24px; line-height:1.55;
}
.pills { display:flex; gap:8px; justify-content:center; flex-wrap:wrap; }
.pill {
  background:rgba(255,255,255,0.10); border-radius:20px;
  padding:6px 14px; font-size:13px; color:#fff;
  border:1px solid rgba(255,255,255,0.10);
}

h2 { font-size:30px; margin:0 0 10px; letter-spacing:-0.4px; }
.sec { padding:64px 0 0; }
.sec > p.intro {
  color:var(--subtitle); font-size:16.5px; max-width:580px; margin:0 0 30px;
}
.centered { text-align:center; }
.centered > p.intro { margin-left:auto; margin-right:auto; }

/* ------------------------------------------------------------------ *
 *  How a round works — three phones abreast
 *
 *  **This replaced an alternating two-column layout, and the reason is the
 *  hole it left.** A screenshot at 270px is around 570px tall; the sentence
 *  beside it is about 150. Centred against each other, every step opened a
 *  void of two hundred blank pixels above and below the text, and three steps
 *  meant three of them. Widening the text or shortening the phone only moves
 *  the problem.
 *
 *  Three abreast has no vertical mismatch to resolve, and it says something
 *  the stacked version could not: the steps are a sequence, and you can see
 *  the whole loop without scrolling.
 * ------------------------------------------------------------------ */
.flow {
  display:grid; grid-template-columns:repeat(3,1fr); gap:26px;
  align-items:start;
}
.flow .item { text-align:center; }
.flow h3 { font-size:18px; margin:14px 0 6px; }
.flow p { color:var(--subtitle); font-size:14.5px; margin:0; line-height:1.55; }

/* A frame, so a screenshot reads as a phone rather than a pasted rectangle —
   and so captures with different source ratios line up instead of stepping.
   `cover` crops rather than squashes, and anchoring to the top keeps the app
   bar, which is what tells you which screen you are looking at. */
.phone {
  border-radius:26px; padding:6px; background:#0B1030;
  border:1px solid rgba(255,255,255,0.20);
  box-shadow:0 18px 40px rgba(0,0,0,0.35);
  transition:transform .3s ease;
}
.phone img {
  width:100%; height:auto; border-radius:21px;
  aspect-ratio:9/17; object-fit:cover; object-position:top;
}
.flow .item:hover .phone { transform:translateY(-6px); }

.num {
  display:inline-flex; align-items:center; justify-content:center;
  background:var(--action); color:#fff;
  width:28px; height:28px; border-radius:50%;
  font-size:14px; font-weight:700; margin-bottom:12px;
}

/* ------------------------------------------------------------------ *
 *  Cards
 * ------------------------------------------------------------------ */
.cards { display:grid; grid-template-columns:repeat(auto-fit,minmax(240px,1fr)); gap:16px; }

/* The four ways to play, two by two.
 *
 * `auto-fit` put three across and left the fourth alone on a row of its own,
 * which reads as a card that did not fit rather than as a set of four. Two by
 * two also gives the longest of them the width its sentence needs — Six
 * Windows describes a whole mode, where the other three are variants of a
 * round and fit in a line. */
.cards.modes { grid-template-columns:repeat(2,1fr); }
.card {
  background:rgba(44,58,150,0.72); border-radius:18px; padding:22px 24px;
  border:1px solid rgba(255,255,255,0.10);
  backdrop-filter:blur(6px);
  transition:transform .25s ease, border-color .25s ease;
}
.card:hover { transform:translateY(-4px); border-color:rgba(255,255,255,0.26); }
.card.flat { background:rgba(20,28,84,0.72); }
.card b { display:block; font-size:16.5px; margin-bottom:5px; }
.card span { color:var(--subtitle); font-size:14.5px; line-height:1.55; }
.tag {
  display:inline-block; background:var(--action); color:#fff;
  font-size:11px; font-weight:700; letter-spacing:0.5px;
  padding:3px 10px; border-radius:12px; margin-bottom:10px;
}
.tag.gold { background:var(--highlight); color:var(--action-dark); }

.band {
  background:rgba(20,28,84,0.78); border-radius:26px; padding:38px 34px;
  margin-top:56px; border:1px solid rgba(255,255,255,0.10);
  backdrop-filter:blur(6px);
}
.band h2 { margin-bottom:8px; }
.band p { color:var(--subtitle); font-size:15.5px; max-width:620px; }
.band ul { color:var(--subtitle); font-size:15px; padding-left:20px; margin:14px 0 0; }
.band li { margin-bottom:6px; }

/* The thank-you, and the ask that goes with it.
 *
 * Placed last, after somebody has read what the game is — an appeal to rate
 * an app arrives as a favour asked of a friend or as a pop-up, and the only
 * thing separating the two is whether anything was given first.
 *
 * No store is named. Half the people reading this are on the wrong platform
 * for whichever one we picked, and the buttons directly below already send
 * each visitor to their own.
 */
.thanks {
  text-align:center; margin-top:56px;
  padding:34px 28px; border-radius:26px;
  background:rgba(249,115,22,0.10);
  border:1px solid rgba(249,115,22,0.30);
}
.thanks h2 { margin:0 0 8px; }
.thanks p {
  color:var(--subtitle); font-size:16px; max-width:560px;
  margin:0 auto;
}
.thanks .stars {
  font-size:26px; letter-spacing:5px; margin-bottom:12px;
  color:var(--highlight);
}

/* Pro keeps a phone beside its text, and here it works: the block runs to
   several paragraphs, so there is something to stand next to. */
.split {
  display:grid; grid-template-columns:250px 1fr; gap:40px; align-items:center;
}

/* ------------------------------------------------------------------ *
 *  Download
 * ------------------------------------------------------------------ */
.download { text-align:center; padding:66px 0 64px; }
.download h2 { margin-bottom:6px; }
.download p.sub { color:var(--subtitle); font-size:15px; margin:0 0 26px; }
.stores { display:flex; gap:14px; justify-content:center; flex-wrap:wrap; }

/* The same pair of buttons, above the fold.
 *
 * **A landing page needs the action in two places.** Somebody arriving from a
 * friend's message already knows what Hidloo is and should not have to scroll
 * past an explanation to install it; somebody arriving cold needs to read
 * first and would ignore a button at the top. One copy always fails one of
 * them. */
.stores.top { margin-top:64px; }
.store {
  display:flex; align-items:center; gap:12px;
  background:#0B1030; color:#fff; text-decoration:none;
  border:1px solid rgba(255,255,255,0.18); border-radius:14px;
  padding:13px 22px; min-width:216px; text-align:left;
  transition:transform .2s, border-color .2s;
}
.store:hover { transform:translateY(-3px); border-color:rgba(255,255,255,0.40); }
.store svg { width:28px; height:28px; flex:none; }
.store .l1 { display:block; font-size:11px; color:#C9CFE8; line-height:1.3; }
.store .l2 { display:block; font-size:17px; font-weight:600; line-height:1.25; }
/* Not yet published: still shown, so nobody wonders whether it exists, but
   visibly not a link. */
.store.soon { opacity:0.5; cursor:default; pointer-events:none; }

footer {
  border-top:1px solid rgba(255,255,255,0.14);
  padding:24px 0 36px; color:var(--subtitle); font-size:13px;
  text-align:center; margin-top:24px; position:relative; z-index:1;
}
footer a { color:var(--subtitle); }

/* ------------------------------------------------------------------ *
 *  Scroll reveal
 *
 *  The class is added by a five-line IntersectionObserver at the end of the
 *  page. It starts visible in the markup and is only hidden once the script
 *  confirms it can put it back — so a browser with JavaScript off, or one
 *  where the script fails, shows a complete page rather than an empty one.
 * ------------------------------------------------------------------ */
.reveal { opacity:0; transform:translateY(18px); transition:opacity .6s ease, transform .6s ease; }
.reveal.in { opacity:1; transform:none; }

@media (max-width:860px) {
  .flow { grid-template-columns:1fr; gap:34px; max-width:300px; margin:0 auto; }
  .split { grid-template-columns:1fr; gap:22px; }
  .split .shot { max-width:250px; margin:0 auto; }
}
@media (max-width:720px) {
  .cards.modes { grid-template-columns:1fr; }
  h1 { font-size:34px; }
  h2 { font-size:25px; }
  .lead { font-size:16.5px; }
  .hero { padding:28px 0 4px; }
  .sec { padding:48px 0 0; }
  .band { padding:28px 22px; border-radius:20px; }
  .store { width:100%; }
  /* En un telefono las pildoras ya ocupan varias lineas, asi que el hueco de
     escritorio se convierte en un salto raro. */
  .stores.top { margin-top:30px; }
}
