> ## Documentation Index
> Fetch the complete documentation index at: /llms.txt
> Use this file to discover all available pages before exploring further.

# Card Resize

> A transitions.dev-inspired card resize primitive that expands a compact card into a detail panel

# Card Resize

A transitions.dev-inspired card resize primitive that expands a compact card into a detail panel

**Card Resize**

```html card-resize.html theme={null}
<!--
  Card Resize - transitions.dev-inspired primitive for HyperFrames.

  Paste the markup, CSS and script into a composition. Use the timeline
  integration note at the bottom as the starting point for deterministic GSAP
  animation.

  Variables. The script reads each one, falls back to the declared default on
  anything missing or unrecognised, and writes the result as a custom property
  the CSS above consumes. The timeline recipe is untouched by them: it keeps
  driving the same width, height and fade, and these decide how the card that
  expands is dressed.

    - surface (paper | ink, default paper): the card colour scheme. paper is
      the original white card with near-black type, ink is a dark card with
      light type for dark frames.
    - accent (ocean | forest | ember, default ocean): the treatment of the media
      thumbnail. ocean is a plain plate, forest adds a fine achromatic hatch,
      ember adds a horizon-and-disc glyph so the plate reads as a photo. All
      three are built from the surface's own ink at fixed alphas, so the
      thumbnail carries no hue on either surface. The three value names are
      inherited from the hue families they used to paint and no longer describe
      what they render; renaming them is a separate, breaking change.
    - elevation (flat | raised | floating, default raised): how far the card
      lifts off the frame, from a tight contact shadow to a deep drop.

  On every default the result is a white card with a quiet ink-tinted thumbnail
  plate under a soft wide drop shadow. Layout, sizing and motion are unchanged.
-->

<div
  class="hf-transition-card-resize"
  data-composition-variables='[
    { "id": "surface", "type": "enum", "role": "style", "label": "Surface", "description": "Card colour scheme: paper is the original white card, ink is a dark card for dark frames.", "default": "paper", "options": [{ "value": "paper", "label": "Paper" }, { "value": "ink", "label": "Ink" }] },
    { "id": "accent", "type": "enum", "role": "style", "label": "Accent", "description": "Treatment of the media thumbnail: a plain plate, a hatched surface, or an image plate with a horizon-and-disc glyph.", "default": "ocean", "options": [{ "value": "ocean", "label": "Ocean" }, { "value": "forest", "label": "Forest" }, { "value": "ember", "label": "Ember" }] },
    { "id": "elevation", "type": "enum", "role": "style", "label": "Elevation", "description": "How far the card lifts off the frame, from a contact shadow to a deep drop.", "default": "raised", "options": [{ "value": "flat", "label": "Flat" }, { "value": "raised", "label": "Raised" }, { "value": "floating", "label": "Floating" }] }
  ]'
>
  <div class="hf-transition-card-media"></div>
  <div class="hf-transition-card-copy">
    <span>Project status</span>
    <strong>Ready to render</strong>
    <p>All scenes validated and queued for export.</p>
  </div>
</div>

<style>
  .hf-transition-card-resize {
    --hf-card-w: 330px;
    --hf-card-h: 132px;
    /* Placeholder ramp: the surface's own ink at fixed alphas, so the media
       plate inverts with the surface instead of needing a second palette. */
    --hf-card-l2: rgba(24, 24, 27, 0.45);
    --hf-card-l3: rgba(24, 24, 27, 0.18);
    --hf-card-hair: rgba(24, 24, 27, 0.14);
    display: grid;
    grid-template-columns: 92px 1fr;
    gap: 18px;
    width: var(--hf-card-w);
    height: var(--hf-card-h);
    padding: 18px;
    overflow: hidden;
    border: 1px solid var(--hf-card-border, #e4e4e7);
    border-radius: 26px;
    background: var(--hf-card-bg, #ffffff);
    color: var(--hf-card-ink, #18181b);
    font-family: Inter, system-ui, sans-serif;
    box-shadow: var(--hf-card-shadow, 0 26px 80px rgba(0, 0, 0, 0.12));
    will-change: width, height, transform;
  }
  .hf-transition-card-media {
    width: 92px;
    height: 92px;
    border-radius: 20px;
    background: var(--hf-card-media, var(--hf-card-l3));
    box-shadow: inset 0 0 0 1px var(--hf-card-hair);
  }
  .hf-transition-card-copy {
    display: grid;
    align-content: center;
    gap: 7px;
    min-width: 0;
  }
  .hf-transition-card-copy span {
    color: var(--hf-card-muted, #71717a);
    font-size: 13px;
    font-weight: 850;
    text-transform: uppercase;
  }
  .hf-transition-card-copy strong {
    white-space: nowrap;
    font-size: 22px;
    letter-spacing: -0.01em;
  }
  .hf-transition-card-copy p {
    margin: 0;
    color: var(--hf-card-muted, #71717a);
    font-size: 15px;
    line-height: 1.45;
  }
</style>

<script>
  (function () {
    "use strict";

    var vars =
      window.__hyperframes && window.__hyperframes.getVariables
        ? window.__hyperframes.getVariables()
        : {};

    // Unrecognised overrides return to their declared defaults.
    function pick(table, value, fallback) {
      return Object.prototype.hasOwnProperty.call(table, value) ? value : fallback;
    }

    var surfaces = {
      paper: {
        bg: "#ffffff",
        ink: "#18181b",
        muted: "#71717a",
        border: "#e4e4e7",
        l2: "rgba(24, 24, 27, 0.45)",
        l3: "rgba(24, 24, 27, 0.18)",
        hair: "rgba(24, 24, 27, 0.14)",
      },
      ink: {
        bg: "#16161a",
        ink: "#fafafa",
        muted: "#a1a1aa",
        border: "#2f2f37",
        l2: "rgba(250, 250, 250, 0.45)",
        l3: "rgba(250, 250, 250, 0.18)",
        hair: "rgba(250, 250, 250, 0.14)",
      },
    };
    // Media treatments, not hue families: the plate itself, the plate hatched,
    // and the plate with a horizon-and-disc glyph that reads as a photo. Each
    // one is written in the surface's own ink ramp, so both surfaces work.
    var medias = {
      ocean: "var(--hf-card-l3)",
      forest:
        "repeating-linear-gradient(135deg, var(--hf-card-hair) 0 2px, transparent 2px 4px), var(--hf-card-l3)",
      ember:
        "radial-gradient(circle 11px at 64px 28px, var(--hf-card-l2) 0 100%, transparent 100%), linear-gradient(to top, var(--hf-card-l2) 0 24px, transparent 24px), var(--hf-card-l3)",
    };
    var shadows = {
      flat: "0 2px 10px rgba(0, 0, 0, 0.1)",
      raised: "0 26px 80px rgba(0, 0, 0, 0.12)",
      floating: "0 46px 120px rgba(0, 0, 0, 0.3)",
    };

    var surface = surfaces[pick(surfaces, vars.surface, "paper")];
    var media = medias[pick(medias, vars.accent, "ocean")];
    var shadow = shadows[pick(shadows, vars.elevation, "raised")];

    var roots = document.querySelectorAll(".hf-transition-card-resize");
    for (var i = 0; i < roots.length; i += 1) {
      roots[i].style.setProperty("--hf-card-bg", surface.bg);
      roots[i].style.setProperty("--hf-card-ink", surface.ink);
      roots[i].style.setProperty("--hf-card-muted", surface.muted);
      roots[i].style.setProperty("--hf-card-border", surface.border);
      roots[i].style.setProperty("--hf-card-l2", surface.l2);
      roots[i].style.setProperty("--hf-card-l3", surface.l3);
      roots[i].style.setProperty("--hf-card-hair", surface.hair);
      roots[i].style.setProperty("--hf-card-media", media);
      roots[i].style.setProperty("--hf-card-shadow", shadow);
    }
  })();
</script>

<!--
  Timeline integration:
  tl.fromTo('.hf-transition-card-resize', { '--hf-card-w': '330px', '--hf-card-h': '132px', opacity: 0, y: 24 }, { '--hf-card-w': '560px', '--hf-card-h': '210px', opacity: 1, y: 0, duration: 0.68, ease: 'power3.inOut' }, 0.35);
  tl.fromTo('.hf-transition-card-copy p', { opacity: 0, y: 12 }, { opacity: 1, y: 0, duration: 0.28, ease: 'power2.out' }, 0.82);
-->
```

Copy npx hyperframes add card-resize to the clipboard

That writes one file: `compositions/components/card-resize.html`.

## Paste it into your composition

Open `compositions/components/card-resize.html` and copy what is inside into your own composition.
The file opens with a comment header that walks you through it.

A component has no size or duration of its own. It takes both from the composition
you paste it into.

## Variables

Every one of these has a default, so the piece works untouched. Set the ones you
want to change on the element:

| Variable | Default | Accepts | What it does |
| - | - | - | - |
| `surface` | `paper` | `paper`, `ink` | Card colour scheme: paper is the original white card, ink is a dark card for dark frames. |
| `accent` | `ocean` | `ocean`, `forest`, `ember` | Treatment of the media thumbnail: a plain plate, a hatched surface, or an image plate with a horizon-and-disc glyph. |
| `elevation` | `raised` | `flat`, `raised`, `floating` | How far the card lifts off the frame, from a contact shadow to a deep drop. |

Set them with `data-variable-values` on the element that mounts it. These are the
defaults, so this behaves exactly like the preview above until you change one:

```html wrap theme={null}
<div
  data-composition-id="card-resize"
  data-composition-src="compositions/components/card-resize.html"
  data-variable-values='{"surface":"paper","accent":"ocean","elevation":"raised"}'
></div>
```

Tagged `video-primitive` `transition-primitive` `transitions-dev-port` `card` `layout`.

## Related topics

* [Browse the complete Catalog](/catalog.md)
* [Add assets and Catalog items in the browser editor](/studio/assets-and-blocks.md)
* [Put blocks together into one video](/concepts/compositions.md)


## Related topics

- [Orbit Card](/catalog/blocks/orbit-card.md)
- [Spotlight Card](/catalog/components/spotlight-card.md)
- [X Follow Card](/catalog/components/x-follow-card.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.