← The library

Portmark

Marketing site for a multimodal freight company

Full template Members only Open the demo Unlock the library
Preview of the Portmark template: a full-screen hero over an aerial photo of a freight yard, the heading “We move the world forward”, two buttons and a news card in the corner.

What it is

A freight company's site, complete: a full-screen hero, four services on a rail, a frame that grows to full screen as you scroll, a case study, a logo band, a testimonial with figures, a globe and its fourteen countries, six news cards, an FAQ, a closing call, a footer. One page, one HTML file.

The design follows that of a commercial Webflow template, of which nothing visual has been kept: the fifteen photographs were regenerated for this template, and its three background videos became still images at the same framing. All the code has been rewritten: the original came to 383 kB of minified CSS, jQuery, four Webflow bundles, a proprietary animation engine, GSAP with three plugins, and a 3D scene streamed as WebAssembly from another domain. Unreadable, and therefore useless for learning from.

That's the whole point: this template isn't here to be admired, it's here to be read, broken and rebuilt.

What you change first

The colours — four lines

Right at the top of assets/css/style.css:

--paper:      #eaecef;  /* page background, light sections */
--paper-lift: #d7dade;  /* raised light sections */
--ink:        #14161a;  /* text, and the dark sections */
--ink-lift:   #23262c;  /* raised dark surfaces */

One thing to grasp before touching anything else: this design has no accent colour at all. It is four neutrals and nothing else — the original declares one accent and never uses it on the page. The single colour in the template is the keyboard focus ring, and it exists in two shades because it has to hold on both surfaces: #2f6df0 on the light one (4.9:1) and #7aa5ff on the dark one (7.4:1). Change one and re-check the other.

The name

Search for “Portmark” in index.html. No CSS class carries the brand name, and the logotype is a word set in the template's own typeface rather than an image: a find-and-replace can't break anything.

The sizes

The type scale is declared once, at the top, as a set of clamp() values. A heading never gets its own media query: you change --h2-size and the whole page follows. The only rules under @media are layout rules.

The fourteen effects, and how they're built

All taken from the data of the original's two animation engines — 113 Webflow events on this page, 42 distinct once deduplicated, plus 26 GSAP scroll triggers carrying 68 tweens. Read out of the stores, then measured in the browser, not by eye.

EffectWhereHow
Headings rising line by line12 headingsthe JS splits them into lines after the webfont loads, each line rides out of its own mask
Scroll reveal20 blocksIntersectionObserver, firing 15% up from the bottom of the screen
Text that fills inthe services pitchwords light up one after another across the scroll, no library
Frame that growsbetween services and clientsthe JS writes a progress variable, the CSS turns it into a width, a height and a corner radius
Hero parallaxhomethe photo drifts at 18% of the scroll, scaled up so no edge is ever uncovered
Bar that flips light and dark7 sectionsthe fixed bar reads the theme of whatever section passes under it
News photo on hover6 cardsfades in over 200 ms while it settles back from a 5% zoom, as in the original
Service photo zoom4 cardsscale: 1.04 over 750 ms
Buttonseverywherea background wipe grows from the bottom edge, the label inverts with it
Underline that sweepscase study linktranslateX from −100% to 0
Date giving way to “Read article”6 cardstwo cells stacked in one grid area, sliding by 110%
Marqueeslogos and footertwo identical rows and CSS keyframes — no JS, and they pause on hover
Mega-menunavigationa <details>: opens on click with no script, plus 90 ms to open and 260 ms to close on a pointer
Carouselsservices and newsnative scroll-snap: dragging, swiping and the keyboard all work without JS

What you should know

  • No external requests. 22 requests on load, all of them local. The original pulled jQuery, four bundles, GSAP and a WebAssembly 3D runtime from four domains.
  • Scroll reveals can't hide the content. The hidden state only exists once the JavaScript has run. Checked by removing the <script>: 12 headings out of 12 stay visible, the six questions still open, the growing frame sits at its final size. The original, meanwhile, hides two dozen selectors behind visibility: hidden until its engine starts.
  • Zero inline styles, zero inline scripts. Verified by serving the folder with the strict policy from _headers, not assumed.
  • The trigger sits 15% up from the bottom of the screen, not at the first pixel as in the original: a block visibly enters instead of having finished before it was seen.
  • The body text is readable. The original sizes everything in vw against an 1800 px canvas with no floor, so its body text lands on 12.8 px at 1440 and 8.8 px at 991. Here the scale stays proportional but every value is floored — the large headings match the original to within a tenth of a pixel, only the small text is lifted.
  • Accessibility: skip link, menu state announced, native FAQ, carousel position announced, visible focus in two shades, decorations hidden from screen readers, animations switched off if the system asks — delays included.
  • Responsive checked at 390, 1440 and 2560 px, on load and after scrolling all the way down, with no horizontal overflow.

What isn't perfect

Better said here than left for you to find out.

  • The globe is a still image. The original streams a photoreal 3D earth as about 2 MB of WebAssembly from another domain. That's a dependency this template won't take, so it's one image with a slow drift and a breathing halo. Same drawing, same framing — the volume and the interaction are gone. It is the most visible difference of the whole page.
  • The three background videos became still images at the same framing. A video from an export is almost never redistributable, and those three weighed 9.5 MB in MP4 alone — for a template that now comes in under two. The frame still grows as you scroll; only the motion inside it is gone.
  • The news card photo only shows on hover, as in the original. There is no hover on a touchscreen, so on a phone that photo is never seen. It does appear on keyboard focus, which the original doesn't do.
  • Splitting the headings into lines costs a reflow when the webfont loads and on every real width change. That's the price of masks that break in the right place at any width.
  • The exclusive accordion needs a recent browser — Chrome 120, Firefox 130, Safari 17.2. On anything older it still opens and closes, but several questions can stay open at once.

It’s waiting for you in the library.

Portmark comes with the subscription, alongside the rest of the library and the full course.

Immediate access · No commitment · Cancel in one click