DEV Community

Cover image for What got more real in 101 Indian monuments built from code
amananandrai
amananandrai

Posted on Edited on AI-assisted

What got more real in 101 Indian monuments built from code

The first version of this site already had 101 Indian monuments in the browser, and not one of them was a downloaded model. Each building was a small function: boxes, cylinders, a lathe for the domes, and one shader that painted stone. That story is in I Built 101 Indian Monuments in the Browser Using Only Code.

This is the second pass, with the pictures from the component guides. The masses were already right. Up close, a dome was still a bare bulb, a screen was still a square grid, and the ground around a building was often the wrong trees or the wrong water. The work since then fills in the joinery, gives a few monuments pieces that only they have, and plants each site with what actually stands there.

The pictures below are the ones in components.md. node tools/shoot-components.mjs draws each shared part alone, in plain light. On the site the same part carries shadows, a photo texture and weathering. What each function takes, and which file it lives in, is in architecture.md and realism.md.

The site is still plain files and three.js, with no build step.

Live: monuments-of-india-nu.vercel.app ยท

Code: github.com/amananandrai/monuments-of-india

If the models or the code are useful to you, or you just like them, please give a star to the Github repo and help other people find the project.

Taj Mahal from the garden: white marble tomb, four minarets and the reflecting pool


How a part gets into a building

Each monument has two files.

  • js/monuments/<name>.js builds the masses: plinth, walls, towers, roofs.
  • js/details/<name>.js adds the finer architecture and the setting, from addDetails(f, g).

f is the group the home view frames. g is the whole site, so a river or a town can sit outside the frame and not pull the camera back.

A few rules hold for every part:

  • Metres, y up. A part stands on y = 0 and faces +z unless its comment says otherwise.
  • The stone is passed in. M.marble, M.red, M.granite and the rest live in js/helpers.js. A one-off stone is mat('#hex', roughness).
  • Merge when the part is done. mergeByMaterial(group) leaves one mesh per material, so a facade of hundreds of small pieces is a handful of draw calls.
  • Two faces never share a plane. An overlay sits 2 to 5 cm off its wall. node check-flicker.mjs <id> from tools/ finds the ones that do not.

Placing a row of windows is a loop around the four faces:

// A window on each face, 11 m out from the centre, the sill 13.6 m up.
for (const a of FACES) {
  d.add(onFace(at(windowFrame(2, 4.2, M.cream, { shape: 'flat' }), 0, 13.6, 0), a, 11.01));
}
Enter fullscreen mode Exit fullscreen mode

at moves a part. onFace turns that move onto a wall: angle 0 is the +z face, the next number is how far out, and a third number walks along the face. aroundCircle and alongFace do the same for a ring of brackets or a cornice. Hundreds of identical merlons or columns go through inst(), one geometry drawn many times.


Domes

Onion dome with a moulded neck, an inverted lotus crown and a finial Lotus dome: shallow ribs, a cup of petals, and a crescent finial
Onion dome: neck, lotus crown, finial Lotus dome: ribs, a cup of petals, a crescent

onionDome(r, m) is a lathe of the shared onion profile. From 1.5 m radius upward (4 m on a phone) it adds two more lathes that ride on the same group, so moving, scaling or ribbing the dome carries them along:

export function onionDome(r, m, {
  crown = r >= (detail.low ? 4 : 1.5),
  neck = r >= (detail.low ? 4 : 1.5),
} = {}) {
  const o = lathe(ONION.map(([a, b]) => [a * r, b * r]), m, 48);
  if (neck) o.add(lathe(DOME_NECK.map(([a, b]) => [a * r, b * r]), m, 32));
  if (crown) o.add(ribbed(lathe(DOME_CROWN.map(([a, b]) => [a * r, b * r]), m, 32), 16, 0.1));
  return o;
}
Enter fullscreen mode Exit fullscreen mode

The neck is the moulding where the bulb springs from the drum. The crown is the inverted lotus, sixteen ribs pressed in by ribbed(), which is the mahapadma the finial rises from. { crown: false } or { neck: false } leaves one off where a monument models its own. The Taj does.

Around that sit the other turned shapes: hemi for a plain hemisphere, persianDome for a pointed double curve, lotusDome for an onion with shallow ribs sitting in a cup of petals, petalRing for the petals themselves, and finial, kalash and crescentFinial for whatever crowns it. A temple pot, a Mughal spike and a crescent are three different functions, because they are three different objects.


Kiosks and turrets

Chhatri: eight columns, a drip-edge eave and a dome on a low drum Mughal chhatri with arches between the columns and a ribbed lotus dome Guldastas: slender Lucknow roof turrets with a tiny onion and a spike
Chhatri Mughal chhatri Guldastas
Minaret with balconies and a chhatri cap Jharokha: an oriel on brackets, screened on three sides
Minaret Jharokha

chhatri(r, h, m, domeM) is the domed kiosk on eight columns that stands on Mughal and Rajput roofs. At full detail each column gets a moulded base and a spreading capital, the eave gets a drip edge, and the dome sits on a low drum. mughalChhatri is the richer one: arches between the columns, a sloping eave, a ribbed lotus dome, and an optional crescent.

guldasta is the Lucknow roof turret, a thin shaft under a tiny onion and a spike. minaret tapers, takes a list of balconies, and is capped by a chhatri. jharokha is the oriel on brackets, screened on three sides, under a roof that can be curved Bengal ('bangla'), domed, or flat. banglaRoof is that curve on its own, for pavilions as well as windows.


Pillars and columns

Classical columns, one plain and one Corinthian with flutes and acanthus Carved temple pillar: square base, octagonal shaft, two carved bands Cluster pillar: a shaft ringed by slender colonnettes
Classical, plain and Corinthian Carved temple pillar Cluster pillar
Yali pillar with a rearing beast and its rider Column trim: plinth, moulding, necking ring and abacus on bare shafts
Yali pillar Column trim on bare shafts

These are different orders, so they are different functions.

  • column(r, h, m, { order }) in js/details/colonial.js is a classical column: plinth, base, tapering shaft, capital. order: 'corinthian' adds flutes and acanthus. entablature and corinthianCapital are what a colonnade carries above it.
  • carvedPillar is a temple pillar: square base, octagonal shaft with two carved bands, a cushion and a capital.
  • clusterPillar is the Vijayanagara pillar, a shaft ringed by slender colonnettes. yaliPillar carries a rearing yali and its rider. Both are sculpted rather than stacked from boxes.
  • columnTrim(list, m, { capM }) dresses a colonnade that was built as bare instanced shafts: a plinth and moulding under each, a necking ring and an abacus at the head. It is on Agra Fort's Diwan-i-Am, the Padmanabhaswamy corridor, Mahakaleshwar's colonnade and the Secretariat loggias at Rashtrapati Bhavan.
  • pilasters are the flat ones, proud of a wall by a few centimetres.

The trim matters because the cheap way to draw forty columns is one instanced cylinder. That reads as a row of poles. Bases and capitals are a second instanced pass, so the shafts stay cheap and the order comes back.


Arches, doors and windows

A wall with an arch cut through it and a moulded ring Iwan: a great recessed arch with its door An arched niche with a half-dome hood
Arch and its ring Iwan Niche
Window in a stone surround, filled with a jali screen Classical door in a pedimented surround Gothic two-light window
Window with a jali Classical door Gothic window
Temple doorway: stepped frame, open leaves, a lamp in the sanctum
Temple doorway

archWall cuts an opening through a wall. archRing is the moulded band around it. niche is a blind arch with a half-dome hood, deep enough to read as a recess. iwan, in js/details/mughal.js, is the great recessed arch of a gate or a tomb front, with its door. arcadeSkin cuts a wall into a row of arched cells, each a door, a screen or a room. mughalDoorway is the smaller pointed door onto a dim interior.

The traditions that are not Mughal have their own doors, because a fanlight is not a torana.

  • templeDoorway is a stepped frame, a hood, timber leaves standing open, a lamp in the sanctum, and guardians. doorLeaves can take spikes, the iron points set against war elephants. doorFrame is the nested carved bands of a post-and-lintel door. interior is the dim room seen through it. templePorch is the small open porch in front.
  • classicalDoor, porch and pediment are the colonial and Indo-Saracenic set. gothicDoor, gothicWindow and oculus are the pointed portal, the two-light window and the round window.
  • windowFrame(w, h, m, { shape, screen }) is a window in a stone surround. screen: jali(m) fills it.

The jali is the part that used to be a square grid. It is now the octagon-and-diamond lattice of Mughal and Rajput screens, one function for the cut and the shading so they cannot drift apart. A 22 cm grid:

float sJaliHole(vec2 uv) {
  vec2 p = abs(fract(uv / 0.22) - 0.5);
  float oct = step(max(p.x, p.y), 0.34) * step(p.x + p.y, 0.47);
  float dia = step(1.0 - p.x - p.y, 0.13);
  return max(oct, dia);
}
Enter fullscreen mode Exit fullscreen mode

Up close, when the holes are large enough on screen not to shimmer, the shader discards the opening. The stone around it still casts the shadow. Far away the lattice stays a shading pattern. Modelling every hole on 101 buildings was never going to fit the triangle budget: 650,000 on a desktop, 300,000 on a phone.

The same trick covers the ornament that should stay cheap: frieze for a band of rosettes, carved(m, kind) for 'script', 'calligraphy', 'pietra', 'reliefs' and 'tiles', plus rosette, medallion, sunburst and lettering for the roundels and the raised names. The pattern lives in the shader. The mesh stays a wall.


Eaves, battlements and bands

Chhajja: a deep sloping eave carried on brackets A row of pointed merlons A railing of posts with pierced screens between them
Chhajja on brackets Merlons Railing

chhajja is the deep sloping eave. chhajjaRing is the round version. bracketGeo is the corbel that carries an eave or a balcony, and placeAll drops one copy at every point in a list. merlons is a row of pointed battlements. On a fort, rampart and bastionCrowns add the parapet, a string course and arrow slits, for a long curtain wall and for round bastions.

railing and railingRing are posts with pierced screens between them. balustrade is the classical version. beltCourse runs a band around a rectangular building, mouldings stacks courses into a plinth or a cornice, dentils is the row of small blocks under that cornice, and panel is a sunk field that can be carved or inlaid. wallWithGaps is a compound wall with openings left for its gates.


Temple towers

A curved Nagara shikhara A whole Nagara temple: sanctum, spire and halls stepping forward A Dravida vimana: stepped storeys with miniature shrines along each edge
Shikhara Nagara temple Dravida vimana
A South Indian gopuram, tier on tier of painted figures A mandap: a pillared hall under a stepped roof A temple niche holding an image
Gopuram Mandap Temple niche

nagaraTemple({ w, h, m, halls, โ€ฆ }) builds a North Indian temple in one call: sanctum, curved spire, and halls stepping out in front. That is why Somnath, in the first article, fits under 1 KB. shikhara is the spire alone, with nagaraProfile and kalingaProfile as two tapers. bhumijaRows sets miniature spires between the bands of a Bhumija tower.

dravidaVimana is the stepped tower over a South Indian sanctum. Each storey's edge carries miniature shrines: kuta at the corners, shala along the sides, laid out by haraRow. gopuram(w, d, h, tiers, seed) is the gate tower, tier on tier of painted stucco figures. The seed is why Meenakshi's towers are not copies of each other. mandap is a pillared hall under a stepped roof. storeyedHall stacks galleries. pidaRoof is the stepped pyramid of slabs on its own.

templeNiche(w, h, m, { figure }) puts an image in a niche. For a long row, idol is the cheap standing figure in relief. trabeateGate is a post-and-lintel gatehouse, with guardians or carved beasts. dwajasthambha is the gold flagstaff in front of the sanctum. grandStair is the broad flight between side walls, with a landing and guardians.

A broad stair between side walls, with a landing A frieze of figures, elephants and horses in relief A statue on a pedestal, with an urn and a pinnacle
Grand stair Figure frieze Statue, urn, pinnacle

figure, guardian, statue and figureFrieze are the sculpted ones. The great statues, Patel, Bahubali, Thiruvalluvar and the Nageshwar Shiva, are each one continuous skin, grown from a signed distance field in js/sdf.js and meshed in the browser, so a limb grows out of a body the way it does in a carving.


Forts and monasteries

A fort gate: a passage through a gatehouse, with towers A rampart and a round bastion with its crown of merlons Tibetan monks' houses: white walls, dark windows, earth roofs
Fort gate Rampart and bastion Monks' houses
A gilded dharma wheel and a victory banner
Dharma wheel and victory banner

fortGate is a gatehouse with a real passage, guard niches, and leaves spiked against elephants. towerDetail adds string courses and arrow slits to a round tower. slitRow is a row of slits along a wall. A gate that is only an arch painted on a wall reads as scenery. A passage you could walk reads as a fort.

For the Himalayan monasteries, tibetanBlock is the whitewashed mass with dark windows under a maroon band. quarters dresses a list of those blocks as monks' houses: windows in black surrounds, doors, beam ends, earth roofs, prayer-flag poles. dharmaWheel is the gilded wheel between two deer over an assembly hall. gyaltsen is the victory banner at a roof corner, shabkhep the pleated awning over a window, parapetDiscs the gilded discs along a parapet. tibetanDoor and tibetanPortico are the painted door and the pillared porch.

The ground under a hill monastery comes from js/details/terrain.js: heightField shapes a surface from a height function, rock where it is steep, scrub or grass where it is not, and mountainRing sets a ring of mountains around a valley.


When the shared kit is not the building

Shared parts get a monument into the right family. They do not make the Taj the Taj. The detail file is where a photograph would disagree with a generic kit.

The Taj Mahal. Each face is a pishtaq: a deep pointed arch in a rectangular frame, roofed by a half-dome, with calligraphy in black marble and inlaid flowers in the spandrels. Smaller arched alcoves with pierced screens sit either side. The parapet carries leaf-shaped merlons, the drum a blind arcade, and the four roof chhatris have arches, an eave and a lotus cap. The minarets take three bracketed balconies. The dome's own lotus is modelled here, so the shared crown stays off.

Konark. The chariot plinth is wrapped in friezes of elephants and daily life, above and below the wheels. The Jagamohana stands on carved mouldings, with an image in a niche either side of each doorway. At the steps of the Natamandira, lions rear over elephants. The horses are sculpted.

Konark Sun Temple: the chariot plinth and the Jagamohana

Hawa Mahal. Each jharokha of the screen projects on a pair of small carved brackets under the sill. The white lime bands along the storeys are carved. A lotus crowns each domed kiosk. Flowering bougainvillea sits at either end of the pavement. The lattice holes stay in the shader, so the stone is still solid and the screens still cast shadows.

Hawa Mahal's street front, a screen of stacked jharokhas

Nageshwar's Shiva. About 30 m to the tips of the trishul, seated as Mahayogi. Matted locks, the crescent and the Ganga, the third eye, Vasuki coiled twice around the neck, rudraksha, a tiger skin and the trishul with its damaru are placed on the signed-distance body with snap(), so they neither float nor sink into the skin.

India Gate, Charminar, the Taj, the Gateway of India and the Old Parliament House carry the most of this layer: roundels, lettering, nested arches, bracketed balconies, jalis, eaves, merlons, lotus domes. The others take the carving of their own tradition. Base mouldings and image niches on the temples. Banded bastions and jharokhas on the forts. Stacked iwans and inlaid stars on the Mughal tombs. Capitals, balustrades and eaves on the colonial buildings.


What stands around the building

Everything that is not the monument comes from js/details/realism.js, with the animals in js/details/animals.js. A part takes a list of spots, [x, z] in metres. Variation comes from a seed, so a visit looks the same as the last one. copies() instances the shape and marks it as dressing, which the home view ignores when it frames the building. Fifty trees are a few draw calls.

Twenty-one kinds of tree, one planter

Broadleaf trees: neem, mango, jamun, tamarind, teak and sal Wide trees: banyan, peepal, chinar and willow Dry trees: ber, babul, khejri and dhok, low and wide
Broadleaf Wide Dry
Column and conifer trees: ashoka, poplar, cypress, casuarina, fir and deodar Coconut palms Clipped, flowering and dry shrubs
Columns and conifers Palms Shrubs

trees(spots, { kind, seed, y, h }) plants every kind. One table, KINDS, holds the default height, the plain crown, the full crown, the leaf and the bark. An unknown kind throws, naming itself. Only the banyan drops aerial roots. Four silhouettes cover the twenty-one: a broadleaf, a wide broadleaf, a dry umbrella, a column, a tiered conifer, and the palm.

Where What stands there
Delhi's avenues Jamun
Bodh Gaya and Sarnath Peepal, the bodhi tree
Kashmir Chinar, pale, on a thick trunk
Ladakh, by the Indus Poplar and willow
Tawang and Rumtek Fir
Ajanta, and the forests Teak and sal
The south Tamarind
Konark and the Shore Temple Casuarina behind the palms
Jaisalmer, Chittorgarh, the dry ridges Khejri, dhok, babul, ber
// Twelve jamun down each side of a path. The seed keeps this avenue the same on every visit.
g.add(trees(
  [...along(12, [-58, 14], [-58, 185]), ...along(12, [58, 14], [58, 185])],
  { kind: 'jamun', seed: 6 }
));
Enter fullscreen mode Exit fullscreen mode

along is an avenue. scatter fills a rectangle and stays out of the building. around is a ring.

Every tree starts as a trunk and one crown. That is all a phone keeps. On a desktop, upgradeTrees() replants that monument's trees with a leaning trunk, limbs, and separate leaf clumps, smallest planting first, for as long as the model stays inside its triangle budget. Palms grow fronds with leaflets. Deodars grow drooping tiers. Six specimen trees become full trees. A forest of 160 usually stays plain. Each tree also takes one of three forms of its kind, so a row is not a row of clones.

shrubs has three readings. Plain is a clipped green bush. dry: true is the grey-green scrub of a dry hill. flowers: '#d0306f' is a dark bush with a smaller muted cap, bougainvillea or marigold, deliberately not a bush made entirely of bloom.

Jaisalmer Fort, with the small dry trees of the Thar in place of a mango orchard

Lamps, flags, boats, towns

Heritage lamp posts, a bench, and bollards with a chain The blue Archaeological Survey of India board on two posts Fountain jets rising and falling into a ring of foam
Lamps, bench, bollards ASI board Fountains
Tibetan prayer flags in five colours The tricolour and a saffron temple pennant Marigold garlands hung between two points
Prayer flags Tricolour and pennant Marigold garlands

lampPosts are fluted iron posts with a scrolled arm and a glass lantern, lit at night. asiBoard is the blue board on two posts. fountains rise and fall into a ring of foam. umbrellas are the cane and cloth shades on bamboo poles. prayerFlags run from point to point in the five colours. garland hangs marigold strands, orange and yellow. flag is a rippling pennant, saffron or the Nishan Sahib. tricolour is the national flag with the Ashoka Chakra.

Country boats, one with a curved hood Ferry launches A cargo ship with crane posts and a funnel
Country boats Ferry launches Cargo ship
Houseboats Market stalls under coloured awnings Town houses of two to five storeys
Houseboats Stalls Town houses

boats, launches, ships and houseboats take a water height, so a boat floats on its lake. stalls stand outside temple gates and in Laad Bazaar at Charminar. townHouses builds two to five storeys with windows, doors and shop signs. tanks is the share of flat roofs that carry a black water tank, 0.7 by default and 0.15 in the fort town at Jaisalmer. cityAround lines streets on every side of a rectangle and leaves the roads in keep open. At Puri, two rows of houses stand outside Jagannath's outer wall, and the Grand Road stays clear.

Cars, taxis and buses on a bridge roadway
Traffic on the two bridges that have it

traffic runs only on the Howrah Bridge and the Bandraโ€“Worli Sea Link. There are no motor vehicles anywhere else, and no people at all, so the monument stays the subject.

Animals

Nandi, the seated bull Elephants, one plain and one with cloth and a howdah A horse and a seated lion
Nandi Elephants Horse and lion
Deer Yaks and camels in saddle cloths
Deer Yaks and camels

nandi sits before a Shiva temple. elephant can be stone or bronze. rideElephant adds cloth and a howdah. lion is a gate guardian, and the Lion Capital. deer stand at Sarnath and Sikandra. yaks are in the mountains. camels wear saddle cloths in the Thar. horse, scaled down, is the ponies at Kedarnath. The larger animals are one continuous skin, heavier than the rest of the kit, and the slowest of them are meshed while the map sits idle.

Ground, water, and the shade at a wall's foot

The first scenery was generous, and often invented. Mango and coconut stood in the desert. Pools sat where the ground is grass. A lawn ended like a tile.

Water was put back where the site has it, and taken out where it had been added. The Tungabhadra runs north of Hampi's Vittala compound, palms on its bank. A stone-rimmed lotus pond lies south of the Mahabodhi railing. The Shahi Baoli stands east of the Bara Imambara, a walled stepwell through an arched gate. Ramappa's lake lies beyond the temple garden. India Gate lost the canals at its piers. Jallianwala Bagh's flame stands on the grass. Rameswaram's sea sits east of the temple, in the town. Maota Lake at Amber mirrors the fort.

Paths are flagstones. Courses are 70 cm deep, stones are 1.1 m long, every third course is half-length, and the courses shift so no joint runs straight through. Each stone has its own tone. Far off, the joints drop away and the floor stays slightly mottled.

float row = floor(uv.y / 0.7);
float wdt = mod(row, 3.0) < 0.5 ? 0.55 : 1.1;
float xo = uv.x + row * 0.37;
Enter fullscreen mode Exit fullscreen mode

A wall meets the grass in shade, not in a hard line. When a monument is shown, it is drawn once from straight above into a 512ร—512 height map (groundShade in js/surface.js). Upward faces darken where that blur stands well above them. Trees are left out of the pass, because they already cast shadows. It runs on phones too.

Ceremonial lawns stay mown: India Gate, the Taj, Victoria, the National War Memorial, both Parliaments. Elsewhere, desktops get grass tufts under about 0.35 m, kept 4 m clear of the monument and off any path.

Close to a building, the camera casts a ray toward its target. If it has entered a solid it steps back out, and it keeps about 1.5 m off a wall in front of it. The home view frames the monument, not the lawns around it, and fifteen monuments open on the view of their best-known photograph: the Taj down its garden, the Red Fort's Lahori Gate, Meenakshi's south gopuram, Hawa Mahal's street front.


Stone that catches the light

The shader still paints joints, veins, brick courses, weathering and a slight tint per piece, from world position, so nothing has to be unwrapped. A one-metre block is the same size on the Qutub Minar as on the walls of Agra Fort. Over that, most stones carry a CC0 photograph from Poly Haven: marble, red and cream sandstone, granite, laterite, dark coursed blocks, fort rubble, plaster, lime, khondalite, concrete and weathered planks.

Each set has a normal map and a roughness map beside the colour, packed by tools/pack-textures.py. On a desktop the shader projects them the same way as the colour, so the stone catches the light as a rough surface. Phones keep the colour map. A set is fetched the first time a monument that uses it is opened, not all of them at startup.

Shadows follow the view. The shadow map used to cover a fixed box around the whole monument, so on a large site one texel was most of a metre. It now stays about three-quarters of the camera's distance from its target, changes in steps so the shadows do not crawl, and is redrawn only when a step is crossed. Desktops start at two device pixels per CSS pixel and step down for that visit if frames come in slower than about 40 a second.

On a phone, below 760 px wide, ambient occlusion and reflections are skipped. Trees stay plain, the ground has no tufts, towns and traffic are thinned, and the heavier carving waits. ?detail=high or ?detail=low on the address chooses.


What I would still not claim

These are interpretations, not survey records. The goal is that someone who knows the building can see its plan, its material and its setting, and that someone who does not can tell a gopuram from a shikhara, and Konark from a generic temple.

The rule from the second pass is small. Repeated joinery lives in one shared part, which is why the pictures above are a catalogue and not 101 separate models. The thing that makes a monument itself lives in that monument's file. The tree and the water are the ones the site's own notes name. A new dome profile does not need a new texture unwrap. A new tree is one row in KINDS.

Adding another monument is still one module and one card in js/data.js.

Which building still looks least like itself? That is the next detail file.


This article was written with AI assistance from the project's source and is disclosed as fully autonomous: it was published without a human rewrite. The component pictures are rendered from the repo by tools/shoot-components.mjs. three.js is MIT. Photo textures are CC0 from Poly Haven. Map data is public domain from Natural Earth.

Top comments (1)

Collapse
 
amananandrai profile image
amananandrai •
  • โญ Star the repo on GitHub โ€” it really helps more people discover it: github.com/amananandrai/monuments-of-india
  • ๐Ÿ’ก Share suggestions โ€” which monuments or details should I add next? Drop it in the comments!
  • ๐Ÿ› Raise issues โ€” spotted an inaccurate monument design, a wrong architecture style, or a bug? Please open an issue.
  • ๐Ÿ”ง Raise PRs โ€” contributions are very welcome, whether it's a new monument, a better feature like monuments according to timeline (eg- Qutub Minar in 1980s), a component fix, or a UI improvement.