All systems operational200+ sites monitoredResponse SLA <4hENES
App · Travel · In build

It reads what you already booked and builds the day around it.

Intiner.ar takes the PDFs, forwarded emails, screenshots and .ics files a trip already produces, reads the flights, hotels and tickets out of them, asks only for the data that changes the plan, and returns a schedule ordered hour by hour.

Intiner.ar

No mark exists to show: none was supplied, and the design system does not draw one. Where a logo would go, the name is set in the display face.

Our role
Product design + build
Surfaces
Public site · web app · mobile · 20 emails
Stage
In build
Languages
Spanish / English
34
Components

Core, forms, travel and billing

20
Transactional emails

Sendable HTML, no images, no webfonts

6
Block types

The system decides where each one goes

5
Step profile wizard

Answers belong to the account, not the trip

What it is

A schedule, not a search engine.

Intiner.ar is a bilingual travel app that turns an idea of a trip into a plan you can follow. You can start from nothing — destination and dates — or load everything you have already booked: flights with layovers, hotels, transfers, activities, tickets. The app works out what each document is, when it happens, and where it belongs in the day.

What it does not do is as defining as what it does. It does not sell or compare flights, hotels or packages. It is not a booking engine, and it never competes with one. It takes what the traveller already has and returns a coherent day-by-day, hour-by-hour schedule that does not clash with anything confirmed.

The product is built on one idea: nothing generic. Every block on the itinerary either cites the file it was read from — "Booking-Miraflores.pdf" — or the preference it was suggested from — "gluten-free and local food, ten minutes from the hotel". If a recommendation cannot explain where it came from, it is not made. The same rule runs through the data: no forecast beyond the seven days the weather API actually returns, no invented flight status, no stock photo standing in for a destination the system has no picture of.

Where it lives
SurfaceWhereWhat
Public siteResponsive webHero, how it works, a sample day, loading your bookings, plans and footer. The main way in, with the ES/EN switch always visible in the bar and one dark section per page, near the close.
Web appDesktop-first, 238px sidebarMy trips · itinerary (day / map / documents) · load bookings · my travel profile · sign-up wizard · administration. The timeline is the main screen; everything else supports it, and there is one primary button per screen.
Mobile appiPhone, 390×844The same screens in one column with a tab bar of four destinations and bottom sheets in place of dialogs. Parity is a rule: a feature that exists on web and not on mobile is a bug, not a platform difference.
Transactional email20 self-contained HTML filesWelcome, verification, incomplete wizard, itinerary ready, flight change, payment failed, quota exhausted, account suspended, trip finished and the rest — each one openable in a browser and pasteable into any sending provider.
What it does

Four things it has to get right.

Each one is a product rule before it is a screen. Break it and you get an interface the product cannot support.

01

Import what is already booked

Four formats in, one schedule out: PDF, a forwarded email, a screenshot, an .ics file. The system reads what each one is and keeps the link back to the file.

  • Flights with layovers, hotels, transfers, tickets — classified automatically
  • Asks only the question that changes the plan: "the AR 1304 stops in Santiago, do you leave the airport?"
  • Every block keeps its source document, so the itinerary can always say where a time came from
  • Data read from a document is corrected in the block dialog, not inline — and the traveller is told that editing it breaks the link to the file
02

Scheduling that holds

The system places blocks itself, and it will not let two of them start at the same time. That is a hard constraint, not a warning.

  • No two blocks share a start time: the field is marked, the first free slot is offered, and save stays disabled
  • Placement by type — a hotel lands on its check-in day at 15:00, a flight opens its day with the airport transfer before it
  • Accepting a recommendation drops it into the real gap and the toast says where it landed: "17:00, in the day’s free slot"
  • Between two blocks, a travel leg gives door-to-door time, distance, traffic and one alternative — and is omitted entirely when the routes API returns nothing
  • A transfer or hotel booked after the itinerary exists is inserted where it belongs, without asking "which day?"
03

A profile that can explain itself

Five questions at sign-up — who you travel with, your pace, food restrictions, how much walking, budget per day — and they belong to the account, not to one trip.

  • Answers are saved once and feed every future recommendation; they are edited later in "my travel profile"
  • Every suggestion cites the preference it came from; if it cannot, it is not shown
  • Editable in place: days, day notes, activity titles and personal notes — Enter confirms, Escape reverts
  • A destination with nothing loaded offers to build the day from the account’s preferences instead of showing an empty page
04

Live data, with its limits visible

Four external integrations, each wrapped in a component that shows its own provenance and its own failure state.

  • Flight status with the old time struck through beside the new one, plus terminal, gate, belt and always a freshness line — a status with no timestamp is worse than none
  • A closed status vocabulary: on time, delayed, cancelled, gate changed, landed. No new labels get invented
  • Weather only inside the seven days the API returns; outside it, a note. Never an average or a historical figure dressed as a forecast
  • The destination photo is resolved once from the places API and stored in the product’s own database; the interface always reads the stored copy, and only an administrator can replace it
  • Any integration is allowed to be missing: the piece shows its honest state and the rest of the itinerary keeps working
Styleguide and branding

Paper before screen. One blue for anything you can touch.

No logo was supplied and the system does not draw one. Everything else — the linen ground, the single action blue, the three status colours, the editorial serif — is a decision taken from the brief and written down next to the reason it was taken.

Palette

Paper 1

#FAF6EF

The ground under everything: a warm linen. There is no pure white and no cool grey anywhere in the system; cards sit one step lighter, on paper-0 #FFFDF9.

Ink 900

#15130F

Primary text and the one dark section a page is allowed. A toasted black rather than #000, so it belongs to the paper.

Azul 600

#1B4DE4

The action colour. Everything you can touch, the day number on the timeline, and the italic ".ar" that stands in for a logo.

Clay 600

#C2542B

Warm secondary: editorial emphasis, and the accent that marks accommodation blocks on the itinerary.

Moss 600

#2F7D53

Confirmed. A status colour only — it is never borrowed for decoration.

Amber 600

#A8760F

Missing a data point, and the admin spend meter above 70% of its quota.

Rust 600

#B3382C

Clash: two blocks fighting for the same hour. Also the meter above 90%.

These are Intiner.ar’s colours, printed here as documentation. Nothing on werun.dev is drawn from them.

Typefaces

Instrument Serif

Display and the wordmark

76 / 54 / 38 / 28px, leading 1.02 to 1.18, tracking negative throughout. A blue italic word is the only emphasis a headline may carry, and never twice in the same headline. It is a declared substitution: no brand font binaries were supplied, so all three families are Google Fonts stand-ins until they are not.

Public Sans

Interface and body

Titles at 24 / 19 / 16, body at 17 / 15 / 13. Sentence case everywhere: capitals appear in exactly two places, the 12px eyebrow at .09em tracking and the day divider’s date line.

DM Mono

Times, flight codes, distances and prices

13px with tabular-nums, so a column of departure times aligns down the page. Every numeric column in the admin screens uses it.

Named, not loaded — this page sets every family above in werun.dev’s own type.

The rules

No logo, and none invented

No mark was supplied, so the system does not draw one. Where a logo would go, the name is set in Instrument Serif with ".ar" in blue italic — on blue, the italic turns clay. The assets folder is left deliberately empty with a written list of what is still owed: logo.svg and a dark-ground version, two or three destination photographs, and a proprietary icon set if one ever exists. Drawing a symbol nobody asked for would have been the quick answer and the wrong one.

#8C8474 is not a text colour

It measures 3.65:1 on paper, so it fails at every size and every level of importance. Muted text uses ink-450 #6F6657, which clears 4.5:1 on all four paper tones; #8C8474 is kept for fills, borders and decorative icons. The rule exists because the data most often set too light is exactly the data the product is obliged to show — a flight’s freshness line, a struck-through departure time, the postal address in a marketing email’s footer.

A status colour is never decorative

Moss, amber and rust mean confirmed, missing data and clash, and nothing else may borrow them. The vocabulary behind them is closed — confirmed, missing data, overlaps, suggested — so no state is ever carried by colour alone. In the bilingual build the semantic key stays in Spanish and a labels prop writes the visible text: passing the English string straight in would produce the right words and a neutral tone, which is the traffic light quietly going out.

Nothing leaves its box, and the box measures itself

The domain cards live in a 320px panel, a mobile sheet and a four-column grid, so the window’s width says nothing about the room they have. They degrade on their own width with container queries: below 380px an itinerary event moves its 64px time rail above the card, below 300px a flight card drops the drawn route and stacks the airport codes. Grids are written minmax(min(Npx,100%),1fr) because a hard minimum overflows the moment its container is narrower, and words never break — a title shrinks a step before it is cut letter by letter.

Stack

What it is built with.

Next.jsReactCSS custom propertiesContainer queriesEditor.jsLucideGoogle PlacesGoogle RoutesGoogle WeatherFlight status APIAnthropic APIHTML email

Every provider lives in an environment variable

No provider, key or model is written into the code — including the model that generates the itineraries, which is chosen by variable so it can change without touching the app. That is a design decision as much as a backend one: the interface never names a provider or a model to a traveller, and API spend in the admin screens is grouped by service — generation, places, routes, weather, flight status — rather than by brand, so the screen stays correct the day a supplier changes.

Bilingual changed the shape of the components

Where a string is both a visible label and the key that picks a colour, the key stays in Spanish and a labels prop writes the text. And no prop is ever a function: these are client components, and a function does not cross the server/client boundary — it fails at runtime, not at compile time. So a trip card receives "8 days" already written rather than a number, the composer takes durations as a map rather than a formatter, and durations travel in minutes with the locale deciding how to print them.

The email heights are measured, not estimated

Twenty sendable files, built the way mail clients demand rather than the way the web has got used to: nested presentation tables, every style inline, no JavaScript, no external sheets, no webfonts and no images at all. Georgia, Arial and Courier New stand in for the three families, and the tokens are inlined as literal hex because no mail client resolves custom properties. Each preview height was measured from the outer table at 640px rather than guessed, because an optimistic number crops the legal footer — which is the one part that cannot be missing.

One API, two loaders

The design system previews without a bundler; the app runs on Next.js with server rendering. Two components load the same thing differently on purpose: the icon wrapper reads Lucide’s geometry from a global here and imports from npm there, because during server rendering there is no window, and a server-drawn fallback against a client-drawn glyph is a hydration mismatch on every single icon. The public API and the markup are identical, so porting a change touches the loader and nothing else.

Building something that has to be honest about its data?

Tell us what it has to do and where the numbers actually come from. We’ll tell you what it takes and who does it.

No commitment. Just a conversation.
Intiner.ar questions