Vista previa en vídeo
GratisHeroAgencia

Asistente de IA

El prompt
ID: exam-bot-ai-study-assistant Category: EdTech / AI Study Assistant Hero Type: hero

Create a single-file HTML+CSS+vanilla-JS hero section with the following exact specifications:

## Tech Stack

* Deliverable filename: `exam-bot-hero.html`  
* Plain HTML \+ CSS \+ vanilla JS. No frameworks, no build step.  
* Fonts — literal copy-pasteable block:

\<link rel="preconnect" href="https://fonts.googleapis.com"\>

\<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin\>

\<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700\&family=Poppins:wght@400;700\&display=swap" rel="stylesheet"\>

- DM Sans (400/500/700) → all UI text: nav, buttons, hero copy, card labels/price-equivalent text  
- Poppins (400/700) → the small file-card description paragraphs only  
* Global reset:

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

html, body{ width:100%; height:100%; overflow:hidden; font-family:'DM Sans', sans-serif; color:\#fff; }

## Canvas & Scaling

* True fullscreen, edge-anchored page. No fixed design canvas, no `transform:scale()`.  
* Do NOT add `transform:scale(...)` anywhere on this page and do NOT wrap content in a fixed-size `.stage-wrap`/`.stage` pair.  
* `.stage{ position:fixed; inset:0; overflow:hidden; background:#000; }` is the fullscreen root.  
* Background is a **video**, not a photo: `.bg-video{ position:fixed; inset:0; width:100%; height:100%; object-fit:cover; z-index:0; }`, rendered as `<video class="bg-video" autoplay muted loop playsinline><source src="https://api.promptsites.net/s3/promptsites/previews/dadc0597-ab41-465c-8fd6-a1c5e5a868c2.mp4" type="video/mp4"></video>`. `autoplay` requires `muted` to work in every browser — never drop `muted`.  
* A bottom fade-to-black sits above the video: `position:fixed; left:0; bottom:0; width:100%; height:152px; background:linear-gradient(to bottom, rgba(0,0,0,0) 0%, #000 100%); z-index:2; pointer-events:none;`  
* Header uses `left:40px; top:22px; right:50px` (edge-anchored both sides, NOT centered) so it stays pinned at any viewport width.  
* Hero title/subtitle anchor from `left:124px` only (not centered) — top offsets are flat px (`top:115px` / `top:270px`), not tied to any other element.  
* The bottom-left icon rail \+ caption row is `left:43px; bottom:29px; right:44px` (bottom-anchored, not top) since it sits near the viewport's bottom edge.  
* The three file cards and the upload button are **top-anchored with flat px values** (`top:354.47px` … `top:583.71px`) — they are NOT tied to the hero title's height, so if the title copy changes length, re-check these offsets don't collide with the subtitle above them.

## Design Tokens

\--green: \#168B52;

\--accent: \#91EB8A;

\--pill: rgba(255,255,255,0.12);

\--text-72: rgba(255,255,255,0.72);

\--text-60: rgba(255,255,255,0.6);

Font sizes used: 70px (title) / 20px / 16px / 15.7px / 11px. Card corner radius: 18.8px. Pill/circle radius: 999px / 25px (buttons).

## Elements

(background first, then header, then hero copy, then bottom caption row, then the three floating cards, then the upload button — visual/DOM order)

### 1\. Background video

* Full-bleed, `object-fit:cover`, `autoplay muted loop playsinline`.  
* Asset (promptsites.net, permanent): `https://api.promptsites.net/s3/promptsites/previews/dadc0597-ab41-465c-8fd6-a1c5e5a868c2.mp4`  
* Do NOT reintroduce a static background photo, gradient wash, or blurred color-dodge glow blobs — this design intentionally has **no** decorative background layers besides the video and the bottom fade.

### 2\. Header — `position:fixed; left:40px; top:22px; right:50px; z-index:10;` flex row, `justify-content:space-between; align-items:center; gap:44px;`

Two children:

- **`.header-nav`** (flex:1, flex row, `justify-content:space-between`):  
  - **`.header-left`** (flex, gap:66px):  
    - Logo icon, 18×18px. Asset: `https://api.promptsites.net/s3/promptsites/previews/b35ac67d-21ab-4e9e-a75f-1c0d3698a5f9.png`  
    - `.nav-pill` (flex, gap:32px), four links, `font-size:16px; line-height:24px; text-transform:capitalize; color:var(--text-72);` — hover: `color:#fff;` (transition 0.2s): **features**, **how it works**, **pricing**, **about**.  
  - **`.header-auth`** (flex, gap:8px): two pill buttons, `height:44px; padding:10px 20px; border-radius:999px; background:var(--pill); color:#fff; font-size:16px; text-transform:capitalize;` — hover: `background:rgba(255,255,255,0.22)`: **Log In**, **Sign Up**.  
- **`.header-rail`** (flex column, gap:16px, align-items:center): three 18×18px icons, `opacity:0.85`. Assets: `https://api.promptsites.net/s3/promptsites/previews/d623e490-a7aa-408e-b8bc-8fea5ee1dd8b.png`, `https://api.promptsites.net/s3/promptsites/previews/3d7a6721-052b-4e9a-b5a0-2ffa432641e5.png`, `https://api.promptsites.net/s3/promptsites/previews/ea9c2502-d51a-4776-8ded-f9ccb844b9f3.png`.  
  * **Fragile coupling:** the middle rail icon asset is reused verbatim in the bottom-left rail (element 4\) — same file, two places. Keep them pointing at the same asset if either is swapped.

### 3\. Hero title — `position:fixed; left:124px; top:115px; width:472px; z-index:10;`

* `font-size:70px; line-height:70px; letter-spacing:-3.4px; font-weight:400; white-space:nowrap;`  
* Exact copy, split across two lines via `<br>` (NOT natural wrap): **"Exam Bot AI"** (white) then **"Study Assistant"** (gradient).  
* `white-space:nowrap` is required on the container — with a plain space instead of `<br>`, font-metric differences between environments can wrap "Exam Bot AI" itself onto two lines and push the whole block down into the subtitle. Do NOT remove the explicit `<br>` in favor of natural wrapping.  
* `.accent` (the "Study Assistant" line): `background:linear-gradient(90deg, #91EB8A 0%, rgba(145,235,138,0.5) 100%); -webkit-background-clip:text; background-clip:text; color:transparent;`  
* **Fragile coupling:** `letter-spacing:-3.4px` is deliberately tight — Figma's own inspector was misleading here (a per-span override of `-0.64px` looked more "correct" but is actually a stray value from an unrelated text style). Do NOT loosen this tracking; it was tuned specifically to keep "Exam Bot AI" from wrapping.

### 4\. Hero subtitle — `position:fixed; left:124px; top:270px; width:446px; z-index:10;`

* Exact copy: **"Examix is your virtual assistant that simplifies the research process effortlessly."**  
* `font-size:20px; line-height:24px; color:#fff;`

### 5\. Bottom-left rail \+ caption — `position:fixed; left:43px; bottom:29px; right:44px; z-index:10;` flex row, `justify-content:space-between; align-items:center;`

- `.bottom-rail` (flex, gap:14px): three 18×18px icons, `opacity:0.85`. Assets: `https://api.promptsites.net/s3/promptsites/previews/bce05995-db47-4574-8c95-01d39c3eb752.png`, `https://api.promptsites.net/s3/promptsites/previews/3d7a6721-052b-4e9a-b5a0-2ffa432641e5.png` (same asset as header element 2), `https://api.promptsites.net/s3/promptsites/previews/2c782bcc-dac8-4ff0-890f-9b60fc7cbf7d.png`.  
- `.bottom-caption` (flex, gap:18px, `max-width:447px`): a 13.66×13.66px icon (`https://api.promptsites.net/s3/promptsites/previews/30505321-3a4b-4bef-8b7a-700d71e2004b.png`, `flex-shrink:0`) \+ paragraph, `font-size:20px; line-height:24px; color:#fff;`, exact copy: **"Upload your file to Examix and it will help you prepare for the exam quickly and painlessly."**

### 6\. Floating file cards — Figma's rotated-bounding-box technique

Each card is built as an **outer flex-centered box sized to the card's rotated footprint**, containing the actual **unrotated** card centered inside it, rotated around its own center via a CSS custom property `--rot`. This is not optional set-dressing — get it wrong and the rotation pivots from the wrong point and the card drifts off its intended position.

.card-box{ position:fixed; display:flex; align-items:center; justify-content:center; z-index:10; pointer-events:none; }

.file-card{ width:211.893px; backdrop-filter:blur(31.328px); background:rgba(255,255,255,0.08); border-radius:18.8px; padding:18.8px; display:flex; flex-direction:column; gap:17.2px; pointer-events:auto; }

Card internals (identical structure for all three):

- `.row` (flex, `justify-content:space-between`): file-type label (`font-size:15.7px; line-height:18.8px;`) \+ a 26.6×26.6px icon slot (folder-icon image at 100%×100%, plus a small overlaid glyph image positioned absolutely inside it — see per-card values).  
- `.desc` (Poppins, `font-size:15.7px; line-height:18.8px;`, bold spans via `<b>` for emphasis words, `.dim` span at `color:rgba(255,255,255,0.7)` for de-emphasized text).

**Card 1 — PNG** (`#box-png`: `left:142px; top:354.47px; width:233.93px; height:279.59px;` / `#card-png`: `height:262.12px; --rot:-5deg;`)

- Folder icon asset: `https://api.promptsites.net/s3/promptsites/previews/dd79b129-5b3a-440d-b743-decb0c3c1610.png`; overlay glyph: `https://api.promptsites.net/s3/promptsites/previews/45998587-19b8-4500-b382-5b36b7f061d0.png` at `position:absolute; width:54%; height:54%; left:23%; top:33%;`  
- Label: **PNG File**. Copy: **"Just upload your PNG to instantly start analyzing, sharing, or securely saving it."**

**Card 2 — DOC** (`#box-doc`: `left:204.4px; top:368.33px; width:229.32px; height:226.92px;` / `#card-doc`: `height:209.24px; --rot:5deg;`)

- Folder icon asset: `https://api.promptsites.net/s3/promptsites/previews/83d47cf0-bdf5-49f0-be2b-903a25e04b62.png`; overlay glyph: `https://api.promptsites.net/s3/promptsites/previews/879bcd37-28dd-48f6-b45f-939cfdd2a4e2.png` at `position:absolute; width:38%; height:26%; left:26%; top:44%;`  
- Label: **DOC File**. `.desc.small` (11px): **"Easily upload your PDF file to begin analyzing, sharing, or storing it securely in seconds."**

**Card 3 — PDF** (`#box-pdf`: `left:174.21px; top:415.32px; width:211.89px; height:209.24px; overflow:hidden; border-radius:18.8px;` / `#card-pdf`: `height:209.24px; position:relative; z-index:1; background:rgba(255,255,255,0.08); --rot:0deg;`)

- Folder icon asset: `https://api.promptsites.net/s3/promptsites/previews/6ae6b557-85a3-45d2-91c4-cc96c9a2945b.png` (no overlay glyph on this one).  
- Label: **PDF File**. Copy: **"Easily upload your PDF file to begin analyzing, sharing, or storing it securely in seconds."**  
- Do NOT add a decorative background graphic behind this card that isn't fully contained by `#box-pdf`'s `overflow:hidden` — an earlier iteration of this design had one and it overflowed the rounded corners badly.

### 7\. Upload button — `position:fixed; left:142.88px; top:583.71px; width:274.12px; height:70.49px; z-index:11;`

* `background:#fff; border:none; border-radius:25px; overflow:hidden;` centers `<span>Upload File</span>` (`font-weight:600; font-size:15.7px; color:#000;`).  
* Hover: `transform:scale(1.06); color:#fff; box-shadow:0 12px 30px rgba(145,235,138,0.4);`  
* Hover fill is a `::before` pseudo-element, `background:linear-gradient(90deg, var(--accent), var(--green)); transform-origin:center;`, resting at `transform:scaleX(0)` and animating to `scaleX(1)` on hover (0.35s ease) — a center-out horizontal wipe, not a plain fade.

## Interactive (JS) Behavior

**Title typewriter** — types "Exam Bot AI" then "Study Assistant" in sequence on page load, character by character, no blinking cursor:

(function(){

  var reduceMotion \= window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  var line1 \= document.getElementById('typeLine1');

  var line2 \= document.getElementById('typeLine2');

  var text1 \= 'Exam Bot AI';

  var text2 \= 'Study Assistant';

  if (reduceMotion){

    line1.textContent \= text1;

    line2.textContent \= text2;

    return;

  }

  function typeInto(el, text, speed, onDone){

    var i \= 0;

    (function step(){

      if (i \<= text.length){

        el.textContent \= text.slice(0, i);

        i++;

        setTimeout(step, speed);

      } else if (onDone){

        onDone();

      }

    })();

  }

  typeInto(line1, text1, 55, function(){

    typeInto(line2, text2, 55);

  });

})();

The title markup must be `<h1 class="hero-title"><span id="typeLine1"></span><br><span class="accent" id="typeLine2"></span></h1>` — empty spans that JS fills in. Do NOT pre-fill them with the final text in HTML; the reveal is the point.

## Animations

Entrance sequence, in load order (no scroll-trigger — this all plays once on page load):

1. **Cards pop up, staggered, one after another** — each card starts below the viewport, small and rotated to its final angle, then bounces up into place:

.file-card{

  opacity:0;

  transform:translateY(90px) scale(0.6) rotate(var(--rot));

  animation:cardPop 0.75s cubic-bezier(0.22, 1.6, 0.4, 1\) forwards;

}

\#card-png{ animation-delay:0.2s; }

\#card-doc{ animation-delay:0.5s; }

\#card-pdf{ animation-delay:0.8s; }

@keyframes cardPop{

  0%{ opacity:0; transform:translateY(90px) scale(0.6) rotate(var(--rot)); }

  65%{ opacity:1; transform:translateY(-14px) scale(1.05) rotate(var(--rot)); }

  100%{ opacity:1; transform:translateY(0) scale(1) rotate(var(--rot)); }

}

2. **Upload button wipes in from the center**, timed to finish right as the last card lands:

.upload-btn{ clip-path:inset(0 50% 0 50% round 25px); animation:btnWipeIn 0.55s cubic-bezier(0.4, 0, 0.2, 1\) 1.15s forwards; }

@keyframes btnWipeIn{

  from{ clip-path:inset(0 50% 0 50% round 25px); }

  to{ clip-path:inset(0 0 0 0 round 25px); }

}

* **Do NOT write the `to` state as `clip-path:inset(0 0 0 0)` without `round 25px`.** `clip-path` does not inherit `border-radius` — omitting the rounding leaves the button permanently clipped to a sharp-cornered rectangle after the animation ends, which then makes the `::before` hover-fill (element 7\) visibly overflow past the button's rounded corners. This is a real bug that shipped once; both keyframe states must include the matching `round 25px`.  
3. Title/subtitle animate via the JS typewriter in "Interactive (JS) Behavior" above, not CSS.  
* `prefers-reduced-motion: reduce` — cards and button render in their final resting state immediately, no animation:

@media (prefers-reduced-motion: reduce){

  .file-card{ opacity:1; animation:none; transform:rotate(var(--rot)); }

  .upload-btn{ clip-path:none; animation:none; }

}

## Z-index Layering

1. `.bg-video` — z-index: 0  
2. `.bottom-fade` — z-index: 2  
3. `.header` — z-index: 10  
4. `.hero-title` / `.hero-sub` — z-index: 10  
5. `.bottom-row` — z-index: 10  
6. `.card-box` (all three) — z-index: 10  
7. `#card-pdf` — z-index: 1 (local, inside its own `#box-pdf` stacking context)  
8. `.upload-btn` — z-index: 11 (above the cards, since it visually sits in front of/below them)

## Notes

* **Fragile coupling — rotated-bounding-box cards.** Each card's outer `.card-box` dimensions (e.g. `233.93×279.59` for the PNG card) are the *rotated* footprint of a `211.893px`\-wide unrotated card at `--rot:-5deg`, not an arbitrary padding value. If you resize a card, you must recompute its bounding box's width/height to match the new rotated footprint, or the flex-centering will visibly misplace it.  
* **Fragile coupling — `clip-path` \+ `border-radius`.** See the callout under Animations — any future `clip-path` added to `.upload-btn` must carry `round 25px` (or whatever the current border-radius is) or the rounded-corner hover fill breaks.  
* **Asset hosting:** all image/icon and video assets are hosted on permanent promptsites.net URLs (`https://api.promptsites.net/s3/promptsites/previews/...`). No Cloudinary or Figma temp URLs remain in this spec.

Please ensure the output is a clean, production-ready single HTML file that renders pixel-identically to this spec, filling the entire browser viewport edge-to-edge at any window size with no letterboxing and no canvas scaling — every block must remain correctly pinned to its respective viewport edge via position:fixed.